Ansible AWX¶
Ansible Towerの機能限定OSS版
Install¶
Ubuntu 20.04の初期設定
$ sudo apt update
$ sudo apt upgrade -y
$ sudo apt install -y git docker docker-compose python3-venv
$ sudo systemctl enable docker
$ sudo systemctl start docker
$ sudo gpasswd -a $USER docker
$ exit
Ansible AWX(v17.0.1)のインストール
$ python3 -m venv ~/.virtualenvs/awx
$ source ~/.virtualenvs/awx/bin/activate
$ pip install ansible==2.9.16 docker docker-compose
$ git clone https://github.com/ansible/awx.git
$ cd awx
$ git switch -c 17.0.1 refs/tags/17.0.1
$ cd installer
$ # venv環境の場合(aptでansibleを入れた場合は不要)
$ sed -i -e "s|/usr/bin/env python3|$(which python)|" inventory
$ # adminパスワードの指定
$ sed -i -e "s|# admin_password=password|admin_password=password|" inventory
$ # デモ用データが不要な場合
$ sed -i -e "s|create_preload_data=True|create_preload_data=False|" inventory
$ export awx_version="17.0.1"
$ ansible-playbook -i inventory install.yml
Warning
デモ用データを入れる場合 ansible-playbook 実行時に [local_docker : Create Preload data]
で引っかかるケースがあります: https://github.com/ansible/awx/issues/8863
数分待って再実行すると上手くいくので、失敗した場合は ansible-playbook を再実行します。
AWX CLIを入れる場合は、追加で以下のコマンド。
$ pip install https://releases.ansible.com/ansible-tower/cli/ansible-tower-cli-latest.tar.gz
Note
サンプルでは --user
が付いてるけど、venv環境であれば外しておかないと ~/.local/bin
に入っちゃうのでパスが通ってなくて混乱する
https://docs.ansible.com/ansible-tower/latest/html/towercli/usage.html#installation
Note
pythonパッケージ的に考えると https://pypi.org/project/awxkit/ に沿って pip install awxkit==17.0.1
とする方が適切かも
CLIを叩いたイメージ。
$ awx --conf.host http://192.168.122.232 --conf.username admin --conf.password password users list
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"type": "user",
"url": "/api/v2/users/1/",
"related": {
"teams": "/api/v2/users/1/teams/",
"organizations": "/api/v2/users/1/organizations/",
"admin_of_organizations": "/api/v2/users/1/admin_of_organizations/",
"projects": "/api/v2/users/1/projects/",
"credentials": "/api/v2/users/1/credentials/",
"roles": "/api/v2/users/1/roles/",
"activity_stream": "/api/v2/users/1/activity_stream/",
"access_list": "/api/v2/users/1/access_list/",
"tokens": "/api/v2/users/1/tokens/",
"authorized_tokens": "/api/v2/users/1/authorized_tokens/",
"personal_tokens": "/api/v2/users/1/personal_tokens/"
},
"summary_fields": {
"user_capabilities": {
"edit": true,
"delete": false
}
},
"created": "2020-12-31T02:50:42.224865Z",
"username": "admin",
"first_name": "",
"last_name": "",
"email": "root@localhost",
"is_superuser": true,
"is_system_auditor": false,
"ldap_dn": "",
"last_login": "2020-12-31T05:01:23.410735Z",
"external_account": null,
"auth": []
}
]
}
インストール直後の容量とDockerプロセス
$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 2.0G 0 2.0G 0% /dev
tmpfs 395M 952K 394M 1% /run
/dev/vda1 29G 4.4G 25G 16% /
tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/vda15 105M 3.6M 101M 4% /boot/efi
tmpfs 395M 0 395M 0% /run/user/1000
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b2d21dee5f16 ansible/awx:16.0.0 "/usr/bin/tini -- /u…" 5 minutes ago Up About a minute 8052/tcp awx_task
6362b27acbeb ansible/awx:16.0.0 "/usr/bin/tini -- /b…" 5 minutes ago Up About a minute 0.0.0.0:80->8052/tcp awx_web
d70fed7fae68 redis "docker-entrypoint.s…" 5 minutes ago Up About a minute 6379/tcp awx_redis
97fdd558233d postgres:10 "docker-entrypoint.s…" 5 minutes ago Up About a minute 5432/tcp awx_postgres
Login¶
URL: http://${ip_address}
User: admin
Pass: password
Note
インストール時にinventoryで指定した admin_password
が設定されています。
Gitlabと連携¶
https://techbloc.net/archives/2389
Proxmox VEにAPIを送るワークフローを設定してみる¶
- インベントリはlocalhost
- job template および workflow template にユーザーから入力を即すためのダイアログを出すにはSurveyを使う(設定の方法はどちらもほぼ同じ)
それをAWX CLIで叩いてみる¶
どうやらAWX CLIで叩くとき workflow_job_templates
のIDは、id(数値)またはユニークであれば名前でも良いらしい。
usage: awx workflow_job_templates get [-h] [-f {json,yaml,jq,human}]
[--filter TEXT] [--conf.color BOOLEAN]
[-v]
id
positional arguments:
id the ID (or unique name) of the resource
(...snip...)
ので、とりあえず作ったワークフローテンプレートに、以下の extra_vars.yaml
をくっつけて投げてみる。
---
vmid: 2232
$ awx --conf.host http://192.168.122.232 --conf.username admin --conf.password password workflow_job_templates launch --extra_vars @extra_vars.yaml "Create VM"
{
"workflow_job": 20,
"ignored_fields": {},
"id": 20,
"type": "workflow_job",
"url": "/api/v2/workflow_jobs/20/",
"summary_fields": {
"organization": {
"id": 1,
"name": "ainoniwa.net",
"description": ""
},
"inventory": {
"id": 1,
"name": "localhost",
"description": "",
"has_active_failures": false,
"total_hosts": 0,
"hosts_with_active_failures": 0,
"total_groups": 0,
"has_inventory_sources": false,
"total_inventory_sources": 0,
"inventory_sources_with_failures": 0,
"organization_id": 1,
"kind": ""
},
"workflow_job_template": {
"id": 9,
"name": "Create VM",
"description": ""
},
"unified_job_template": {
"id": 9,
"name": "Create VM",
"description": "",
"unified_job_type": "workflow_job"
},
"created_by": {
"id": 1,
"username": "admin",
"first_name": "",
"last_name": ""
},
"modified_by": {
"id": 1,
"username": "admin",
"first_name": "",
"last_name": ""
},
"user_capabilities": {
"delete": true,
"start": true
},
"labels": {
"count": 0,
"results": []
}
},
"created": "2020-12-31T05:11:53.935340Z",
"modified": "2020-12-31T05:11:53.975535Z",
"name": "Create VM",
"description": "",
"unified_job_template": 9,
"launch_type": "manual",
"status": "pending",
"failed": false,
"started": null,
"finished": null,
"canceled_on": null,
"elapsed": 0.0,
"job_args": "",
"job_cwd": "",
"job_env": {},
"job_explanation": "",
"result_traceback": "",
"workflow_job_template": 9,
"extra_vars": "{\"username\": \"root@pam\", \"password\": \"px-r708uf\", \"api_endpoint\": \"https://pve.ainoniwa.net\", \"node\": \"pve01\", \"vmid\": 2232}",
"allow_simultaneous": false,
"job_template": null,
"is_sliced_job": false,
"inventory": 1,
"limit": "",
"scm_branch": "",
"webhook_service": "",
"webhook_credential": null,
"webhook_guid": ""
}
launchした時にワークフロージョブのIDが返ってくるので、これを参照して状態を確認する。
$ awx --conf.host http://192.168.122.232 --conf.username admin --conf.password password workflow_jobs get 20
{
"id": 20,
"type": "workflow_job",
"url": "/api/v2/workflow_jobs/20/",
"summary_fields": {
"organization": {
"id": 1,
"name": "ainoniwa.net",
"description": ""
},
"inventory": {
"id": 1,
"name": "localhost",
"description": "",
"has_active_failures": false,
"total_hosts": 0,
"hosts_with_active_failures": 0,
"total_groups": 0,
"has_inventory_sources": false,
"total_inventory_sources": 0,
"inventory_sources_with_failures": 0,
"organization_id": 1,
"kind": ""
},
"workflow_job_template": {
"id": 9,
"name": "Create VM",
"description": ""
},
"unified_job_template": {
"id": 9,
"name": "Create VM",
"description": "",
"unified_job_type": "workflow_job"
},
"created_by": {
"id": 1,
"username": "admin",
"first_name": "",
"last_name": ""
},
"modified_by": {
"id": 1,
"username": "admin",
"first_name": "",
"last_name": ""
},
"user_capabilities": {
"delete": true,
"start": true
},
"labels": {
"count": 0,
"results": []
}
},
"created": "2020-12-31T05:11:53.935340Z",
"modified": "2020-12-31T05:11:54.172087Z",
"name": "Create VM",
"description": "",
"unified_job_template": 9,
"launch_type": "manual",
"status": "successful",
"failed": false,
"started": "2020-12-31T05:11:54.169086Z",
"finished": "2020-12-31T05:12:00.576110Z",
"canceled_on": null,
"elapsed": 6.407,
"job_args": "",
"job_cwd": "",
"job_env": {},
"job_explanation": "",
"result_traceback": "",
"workflow_job_template": 9,
"extra_vars": "{\"username\": \"root@pam\", \"password\": \"pve-password\", \"api_endpoint\": \"https://pve.ainoniwa.net\", \"node\": \"pve01\", \"vmid\": 2232}",
"allow_simultaneous": false,
"job_template": null,
"is_sliced_job": false,
"inventory": 1,
"limit": "",
"scm_branch": "",
"webhook_service": "",
"webhook_credential": null,
"webhook_guid": ""
}
"status": "successful"
が確認できれば、とりあえず良いだろう。
pythonからrequestsで叩く¶
- https://docs.ansible.com/ansible-tower/3.2.6/html/towerapi/launch_jobtemplate.html
- https://qiita.com/sky_jokerxx/items/749b37ffea0d7f0a8cbf
>>> import requests
>>> import json
>>> base_url = "http://192.168.122.232"
>>> wf_launch = "/api/v2/workflow_job_templates/9/launch/"
>>> headers = {"Content-Type": "application/json"}
>>> auth = ("admin", "password")
>>> launch_ret = requests.post(base_url + wf_launch, headers=headers, auth=auth, data='{"extra_vars": "vmid: 2232"}')
>>> print(json.dumps(launch_ret.json(), indent=2))
{
"id": 23,
"type": "workflow_job",
"url": "/api/v2/workflow_jobs/23/",
"related": {
"created_by": "/api/v2/users/1/",
"modified_by": "/api/v2/users/1/",
"unified_job_template": "/api/v2/workflow_job_templates/9/",
"workflow_job_template": "/api/v2/workflow_job_templates/9/",
"notifications": "/api/v2/workflow_jobs/23/notifications/",
"workflow_nodes": "/api/v2/workflow_jobs/23/workflow_nodes/",
...
"is_sliced_job": false,
"inventory": 1,
"limit": "",
"scm_branch": "",
"webhook_service": "",
"webhook_credential": null,
"webhook_guid": ""
}
>>> ret = requests.get(base_url + launch_ret.json()["url"], headers=headers, auth=auth)
DjangoのQuerySetが使えるので、以下のようなフィルタも書ける。
>>> requests.get(base_url + "/api/v2/workflow_job_templates/", headers=headers, auth=auth, params={"name__iexact":"Create"}).json()
{'count': 0, 'next': None, 'previous': None, 'results': []}
>>> requests.get(base_url + "/api/v2/workflow_job_templates/", headers=headers, auth=auth, params={"name__iexact":"Create VM"}).json()
{'count': 1, 'next': None, 'previous': None, 'results': [{'id': 9, 'type': 'workflow_job_template', 'url': '/api/v2/workflow_job_templates/9/', 'related': {'created_by': '/api/v2/users/1/', 'modified_by': '/api/v2/users/1/', 'last_job': '/api/v2/workflow_jobs/139/', ... , 'survey_enabled': True, 'allow_simultaneous': False, 'ask_variables_on_launch': False, 'inventory': 1, 'limit': '', 'scm_branch': '', 'ask_inventory_on_launch': False, 'ask_scm_branch_on_launch': False, 'ask_limit_on_launch': False, 'webhook_service': '', 'webhook_credential': None}]}