LoginSignup
6
5

More than 5 years have passed since last update.

Ansible TowerのAPI経由からテンプレートに変数を渡して実行してみた

Last updated at Posted at 2018-03-20

Ansible TowerのAPI経由からテンプレート実行で変数(extra_vars)を渡すやり方で少しハマったのでメモっておきます。

環境

項目 バージョン
OS RHEL7.4
Ansible Tower 3.2.3
python 3.4

Ansible Tower APIドキュメント

http://docs.ansible.com/ansible-tower/3.1.4/html/towerapi/index.html

検証ストーリー

  • Playbookはローカルの /var/lib/aws/projects に直接作成したものを使います
  • REST APIから変数をセットした情報を渡してテンプレートを実行します
  • APIはpythonスクリプトから実行します

Ansible Tower設定

プロジェクト設定

スクリーンショット 2018-03-20 22.08.40.png

テンプレート設定

注意点として 追加変数起動プロンプト にチェックを入れてください。

チェックが入っていない場合は、変数をAPI経由で渡しても無視されます。(デフォルトは無視になっています)

スクリーンショット 2018-03-20 22.09.39.png

テスト用Playbook

テスト用Playbookは以下の2つを使ってみます。

msgで変数値を出力

test.yml
---
- name: TEST Playbook
  hosts: localhost
  tasks:
    - debug: msg="{{ MSG }}"

ループで変数値を出力

test.yml
---
- name: TEST Playbook
  hosts: localhost
  tasks:
    - debug:
        msg: "{{ item }}"
      with_items: "{{ str_list }}"

APIを実行するツール

ソース

検証ツールとして以下のものを使用します。

ansible-tower-api-tool.py
#!/usr/bin/env python3
from getpass import getpass
import argparse
import sys
import json
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

def options():
    parser = argparse.ArgumentParser(prog="ansible-tower-api-tool.py",
                                     add_help=True,
                                     description="Ansible Towerのテンプレートを実行するツール")
    parser.add_argument("--host",
                        type=str, required=True,
                        help="Ansible TowerサーバのIPまたはホスト名")
    parser.add_argument("--username", "-u",
                        type=str,default="admin",
                        help="Ansible Towerアカウント(default:admin)")
    parser.add_argument("--password", "-p",
                        type=str,
                        help="Ansible Towerアカウントのパスワード")
    parser.add_argument("--template", "-t",
                        type=str, required=True,
                        help="実行するテンプレート名")
    parser.add_argument("--data", "-d",
                        type=eval,
                        help="テンプレートのextra_vars")

    args = parser.parse_args()
    if(not(args.password)):
        args.password = getpass(prompt="Ansible Tower Password: ")

    return args

def get_header():
    headers = { "Content-Type": "application/json" }
    return headers

def get_cred(username, password):
    cred = {
        'username': username,
        'password': password
    }
    return cred

def create_url(host, path):
    url = "https://%s%s" % (host, path)
    return url

def get_token(host, cred):
    url = create_url(host, "/api/v2/authtoken/")
    r = post(url, get_header(), cred)

    if(r.status_code == 200):
        token = json.loads(r.text)['token']
        return token
    else:
        print('Token acquisition error.')
        sys.exit(1)

def get(url, headers):
    r = requests.get(url,
                     headers=headers,
                     verify=False)

    return r

def post(url, headers, data):
    r = requests.post(url,
                      headers=headers,
                      data=json.dumps(data),
                      verify=False)

    return r

if __name__ == '__main__':
    # オプションを取得
    args = options()

    # 認証Tokenを取得
    cred = get_cred(args.username, args.password)
    token = get_token(args.host, cred)

    # ヘッダー情報を生成
    headers = get_header()
    headers["Authorization"] = "Token " + token

    # テンプレードID取得
    url = create_url(args.host, "/api/v1/job_templates")
    r = get(url, headers)

    for i in json.loads(r.text)['results']:
        if(i["name"] == args.template):
            template_launch_url = i["related"]["launch"]
            break

    if(not("template_launch_url" in locals())):
        print("%s template not found" % args.template)
        sys.exit(1)

    # テンプレートを実行
    url = create_url(args.host, template_launch_url)
    r = post(url, headers, args.data)
    print(r.status_code)

使い方

$ ./ansible-tower-api-tool.py --host AnsibleTowerのIP -t テンプレート名 -d key,valueをセットしたdict

検証

MSGの変数に値を入れてみる

MSGTEST Message を入れてAPIを実行してみます。

$ ./ansible-tower-api-tool.py --host 192.168.0.234 -t TEST -d '{"extra_vars": {"MSG":"TEST Message"}}'
Ansible Tower Password:
201

スクリーンショット 2018-03-20 22.30.13.png

ループで実行してみる

str_list に配列で Mes1 Mes2 Mes3 を入れてAPIを実行してみます。

$ ./ansible-tower-api-tool.py --host 192.168.0.234 -t TEST -d '{"extra_vars": {"str_list":["Mes1","Mes2","Mes3"]}}'
Ansible Tower Password:
201

スクリーンショット 2018-03-20 22.34.52.png

まとめ

Ansible TowerのAPI経由から変数を渡す場合は 追加変数起動プロンプト にチェックが入っていることが必要です。

これは、API経由(以下URL)からでも確認が可能です。

URL
https://$ansible_tower_ip/api/v1/job_templates/$TemplateID/launch/

以下が、GETした時の結果例です。

ask_variables_on_launchtrue になっている必要性があります。

{
  "can_start_without_user_input": false,
  "passwords_needed_to_start": [],
  "ask_variables_on_launch": true,
  "ask_tags_on_launch": false,
  "ask_diff_mode_on_launch": false,
  "ask_skip_tags_on_launch": false,
  "ask_job_type_on_launch": false,
  "ask_limit_on_launch": false,
  "ask_verbosity_on_launch": false,
  "ask_inventory_on_launch": false,
  "ask_credential_on_launch": false,
  "survey_enabled": false,
  "variables_needed_to_start": [],
  "credential_needed_to_start": false,
  "inventory_needed_to_start": false,
  "job_template_data": {
    "id": 13,
    "description": "",
    "name": "TEST"
  },
  "defaults": {
    "credential": {
      "id": 2,
      "name": "root"
    },
    "job_tags": "",
    "extra_vars": "",
    "verbosity": 0,
    "job_type": "run",
    "diff_mode": false,
    "skip_tags": "",
    "limit": "",
    "inventory": {
      "id": 2,
      "name": "TEST Host List"
    },
    "vault_credential": {
      "id": null,
      "name": null
    }
  }
}
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5