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設定
プロジェクト設定
テンプレート設定
注意点として 追加変数
の 起動プロンプト
にチェックを入れてください。
チェックが入っていない場合は、変数をAPI経由で渡しても無視されます。(デフォルトは無視になっています)
テスト用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の変数に値を入れてみる
MSG
に TEST Message
を入れてAPIを実行してみます。
$ ./ansible-tower-api-tool.py --host 192.168.0.234 -t TEST -d '{"extra_vars": {"MSG":"TEST Message"}}'
Ansible Tower Password:
201
ループで実行してみる
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
まとめ
Ansible TowerのAPI経由から変数を渡す場合は 追加変数
の 起動プロンプト
にチェックが入っていることが必要です。
これは、API経由(以下URL)からでも確認が可能です。
URL |
---|
https://$ansible_tower_ip/api/v1/job_templates/$TemplateID/launch/ |
以下が、GETした時の結果例です。
ask_variables_on_launch
が true
になっている必要性があります。
{
"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
}
}
}