Contents
GitLabのリポジトリに対してPushをトリガーにAnsible Towerのワークフローをキックして結果のステータスをGitLabのリポジトリへ反映する方法です。
イメージ
以下はイメージ図です。

ユーザーがリモートのリポジトリにpushをしたタイミングでWebhookサーバにWebhookを飛ばしてAnsible TowerのWFを実行し結果をGitLabに反映します。
環境
| コンポーネント | バージョン | 備考 | 
|---|---|---|
| CentOS | 7.7 | Webhookサーバ | 
| RHEL | 7.6 | Ansible Towerサーバ | 
| GitLab | 12.2.5 | |
| Ansible Tower | 3.5.1 | |
| Webhook | 2.6.10 | Go製 | 
Webhook
Webhookインストール
インストール方法は以下を参照してください。
Webhook設定
Webhookは以下のように設定します。
| 
					 1 2 3 4  | 
						(venv) [root@Webhook01 ~]# cd /opt/ (venv) [root@Webhook01 opt]# mkdir ansible-tower-wf (venv) [root@Webhook01 ansible-tower-wf]# vi hooks.json  | 
					
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39  | 
						[     {         "id": "ansible-tower-wf",         "execute-command": "/opt/ansible-tower-wf/run-ansible-tower-wf.sh",         "command-working-directory": "/opt",         "pass-arguments-to-command":         [             {                 "source": "payload",                 "name": "project_id"             },             {                 "source": "payload",                 "name": "checkout_sha"             },             {                 "source": "payload",                 "name": "project.web_url"             }         ],         "trigger-rule":         {             "and":             [                 "match":                 {                     "type": "value",                     "value": "GQaATMBq8APLvGuzp4bca87eBHcT05",                     "parameter":                     {                         "source": "header",                         "name": "X-Gitlab-Token"                     }                 }             ]         }     } ]  | 
					
trigger-rule の X-Gitlab-Token に設定してある value は以下のコマンドでランダムに生成しています。
| 
					 1 2 3  | 
						(venv) [root@Webhook01 ansible-tower-wf]# cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 30 ; echo GQaATMBq8APLvGuzp4bca87eBHcT05  | 
					
これは、GitLabからWebhookを受け取ったときに同じ値のX-Gitlab-Tokenヘッダーがあれば実行すると言うルールです。
Webhookで実行されるスクリプトの引数は以下の通りです。
| 引数番号 | name | 説明 | 
|---|---|---|
| 1 | project_id | プロジェクトのID | 
| 2 | checkout_sha | リポジトリへコミットしたハッシュ値 | 
| 3 | project.web_url | リポジトリへのWeb URL | 
スクリプト
Webhookの条件が満たされた場合に実行されるスクリプトは以下のように作成しています。
| 
					 1 2  | 
						(venv) [root@Webhook01 ansible-tower-wf]# vi run-ansible-tower-wf.sh  | 
					
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17  | 
						#!/bin/bash # GitLab Variables project_id=$1 commit_hash=$2 gitlab_server=`echo $3 | cut -d '/' -f 3` gitlab_token='H4_N99yzHE8FepTyrpQu' # Ansible Tower Variables ansible_tower='192.168.0.64' ansible_user='admin' ansible_password='redhat' ansible_wf='ansible-tower-gitlab-wf' source /opt/ansible-tower-wf/venv/bin/activate && tower-cli workflow_job launch -W $ansible_wf -e "{\"project_id\": $project_id, \"commit_hash\": $commit_hash, \"gitlab_server\": $gitlab_server, \"GitLab_TOKEN\": $gitlab_token }" \           -h $ansible_tower -u $ansible_user -p $ansible_password --insecure  | 
					
スクリプトで取り扱う変数は以下の通りです。
| 変数名 | 説明 | 備考 | 
|---|---|---|
| project_id | GitLabのプロジェクトのID | 1番目の引数 | 
| commit_hash | GitLabのコミットハッシュ値 | 2番目の引数 | 
| gitlab_server | GitLabサーバのホスト | 3盤面の引数 | 
| gitlab_token | GitLabで生成したToken | |
| ansible_tower | Ansible Towerのホスト | |
| ansible_user | Ansible Towerのユーザー | |
| ansible_password | Ansible Towreのパスワード | |
| ansible_wf | 実行するAnsible Towerのワークフロー名 | 
gitlab_token は次のGitLabのTokenの発行で発行した値を指定します。
GitLab
Tokenの発行
GitLabのリポジトリに外部からアクセスするようのトークンを生成します。
ユーザー の Settings をクリックします。
Access Token をクリックして Name を入力し api にチェックを入れ Create personal access token をクリックします。
生成されたトークンを控えておきます。
Webhook設定
リポジトリの Settings の Integrations をクリックします。
URL にwebhookのURLを入力し SecretToken にコマンドでランダムに生成した値を入れ Add webhook をクリックします。
Ansible Tower
Playbook
Playbookは以下の3つを作成しました。
| Playbook | 説明 | 
|---|---|
| main.yml | pingモジュールを実行する | 
| gitlab-build-status-running.yml | GitLabリポジトリステータスを running にする | 
| gitlab-build-status-success.yml | GitLabリポジトリステータスを success にする | 
| gitlab-build-status-failed.yml | GitLabリポジトリステータスを failed にする | 
GitLabのリポジトリステータスはWeb API経由で変更しています。
APIドキュメントは以下を参照してください。
main.yml
| 
					 1 2 3 4 5 6 7  | 
						--- - name: Ping   hosts: all   gather_facts: no   tasks:     - ping:  | 
					
gitlab-build-status-running.yml
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13  | 
						--- - name: GitLab Status Updte   hosts: localhost   gather_facts: no   tasks:     - name: GitLab build status is running       uri:         url: "http://{{ gitlab_server }}/api/v4/projects/{{ project_id }}/statuses/{{ commit_hash }}?state=running"         method: POST         headers:           PRIVATE-TOKEN: "{{ GitLab_TOKEN }}"         status_code: 201  | 
					
gitlab-build-status-success.yml
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13  | 
						--- - name: GitLab Status Updte   hosts: localhost   gather_facts: no   tasks:     - name: GitLab build status is running       uri:         url: "http://{{ gitlab_server }}/api/v4/projects/{{ project_id }}/statuses/{{ commit_hash }}?state=success"         method: POST         headers:           PRIVATE-TOKEN: "{{ GitLab_TOKEN }}"         status_code: 201  | 
					
gitlab-build-status-failed.yml
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13  | 
						--- - name: GitLab Status Updte   hosts: localhost   gather_facts: no   tasks:     - name: GitLab build status is running       uri:         url: "http://{{ gitlab_server }}/api/v4/projects/{{ project_id }}/statuses/{{ commit_hash }}?state=failed"         method: POST         headers:           PRIVATE-TOKEN: "{{ GitLab_TOKEN }}"         status_code: 201  | 
					
Project設定
Template設定
ansible-tower-gitlab-wf-main
main.ymlを実行するTemplateです。
GitLab Build Status Running
gitlab-build-status-running.ymlを実行するTemplateです。
GitLab Build Status Success
gitlab-build-status-success.ymlを実行するTemplateです。
GitLab Build Status Failed
gitlab-build-status-failed.ymlを実行するTemplateです。
Workflow Template設定
ansible-tower-gitlab-wf
今回作成したPlaybookを組み合わせて実行させるWorkflow Templateです。
SURVEYは以下のようにしています。
GitLab_TOKEN をAnsible Towerの履歴から見れないようにマスクしています。
Workflowは以下のように作成しています。
| 番号 | 説明 | 
|---|---|
| (1) | GitLabのリポジトリステータスをrunningに変更 | 
| (2) | テスト処理、ここでは例としてpingするだけのPlaybookを実行 | 
| (3) | 問題なければGitLabのステータスをsuccessに変更 | 
| (4) | 失敗した場合はGitLabのステータスをfailedに変更 | 
デモ
実際に動かしてみたデモです。
Demo to run CI with Ansible Tower workflow by combining Ansible Tower and GitLab from sky_joker on Vimeo.
最後に
Ansible TowerとGitLabとWebhookを組み合わせる事でAnsible TowerのワークフローでCIちっくなことが出来そうですね。
ただ、今まで通りのCIツール(TravisとかShippabletとかJenkinsなど)ではないので、CIファイルにコマンド書きではなくPlaybookを作る必要があります。
なので、向き不向きがかなり分かれそうな感じがします。
どういったユースケースの場合だと便利かは今後も検証して確認してみようと思います 🙂
それでは、みんなでハッピーオートメーション!











