zaki work log

作業ログやら生活ログやらなんやら

[Ansible] playbookと別リポジトリ管理のroleを実行するにはroles/requirements.ymlを使う (CLI / Tower)

playbookのリポジトリとroleのリポジトリを分けた場合に、どうやって別リポジトリのroleをplaybookから実行するかについて。半年以上前に情報として聞いてはいたけれど試してなかったので実際に動かしてみた。

roleのリポジトリ

ansible-galaxy role init <role-name>で作成できるファイル群がリポジトリ直下になるようにrole作成。
この際、meta/main.ymlが必須。(無いとplaybook側で…というかansible-galaxy installコマンドでイントールできない)
リポジトリのファイル構成例としてはこんな感じ。

$ tree
.
├── README.md
├── meta
│   └── main.yml
├── tasks
│   └── main.yml
└── vars
    └── main.yml

実装例は以下。

github.com

サンプルroleの中身はこんな感じ。
(curryって変数はvars/main.ymlで定義)

---
# tasks file for sample_role
- name: sample role start
  debug:
    msg: "this is sample role"

- name: print value
  debug:
    msg: 'curry: {{ curry }}'

これをリモートリポジトリにpushしておくと、ansible-galaxy installでroleをインストールできるようになる。

playbookのリポジトリ

github.com

roleのインストール

roles/requirements.ymlに使用するroleの情報を記述する。
例としてはこんな感じ。

---
- name: hogehoge
  src: https://github.com/zaki-lknr/ansible-sample-role.git
  version: main

このrequirements.ymlを引数にansible-galaxy install -r roles/requirements.ymlを実行すると、(デフォルトでは)~/.ansible/roles/hogehoge以下へroleがインストールされる。
書式についてはInstalling multiple roles from a fileを参照。
あとscmというパラメタに、デフォルトはgitだけどhgも指定できる模様。そういやTowerもMercurialが選択肢にあったな。

(追記) role(のリポジトリ)が更新されてる場合は、-f も付与してアップデート(強制上書きインストール)が必要。
(少し前にアップデートオプションが追加されたような気がしたけど、あれってコレクションの場合(ansible-galaxy collection)のオプションだったようだ)

$ ansible-galaxy install -fr roles/requirements.yml

playbook

playbookはこの通り、hogehogeというroleを実行するように記述。

---
- hosts: localhost
  gather_facts: false

  roles:
  - hogehoge

事前に~/.ansible/roles/hogehogeへ対象roleをインストール済みであれば、このplaybookをansible-playbookで普通に実行すればhogehoge roleが呼ばれて普通に実行できる。

roleインストール先を変更したい場合

ansible.cfgなどで

[defaults]
roles_path = /var/tmp/ansible/roles

とか書いておけば指定可能。
詳しくはDEFAULT_ROLES_PATH参照。

Towerの場合

前述「playbookのリポジトリ」の内容をGitリモートリポジトリにpushしておき、Towerでは通常通りにこのリポジトリを使うプロジェクトを作成する。
プロジェクトの同期のタイミングでroles/requirements.ymlのroleが同期されるので、あとはこちらも普通に実行できる。
よくよく見ると、collections/requirements.yml もここで参照されてるんだな。

roleのリポジトリで更新を行った場合はプロジェクトの再同期が必要。(と思う。自動設定は…Webhookとかで出来るかな?)
手元の環境ではジョブテンプレートの再実行だけではroleの内容は更新されなかった。
※ (追記) ↑ プロジェクトの設定で「起動時のリビジョン更新」にチェックを入れておけば、ジョブ実行毎にリポジトリの情報が更新されるので、実行時にroleも更新される。

ジョブを実行したときのログはこの通りで、指定のroleがちゃんと実行されている。

これは何ができるの?

複数のリポジトリでそれぞれの目的の処理を行うplaybookを作成してて、でもいくつかのplaybookで似たような処理が出てきたので共通化したい、みたいな場合に処理を集約できる。

環境

AnsibleはCentOS7
Pythonがちょっと古い。

$ ansible --version
ansible [core 2.11.2] 
  config file = /home/zaki/.ansible.cfg
  configured module search path = ['/home/zaki/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/zaki/src/ansible-sample/venv/ansible4/lib64/python3.6/site-packages/ansible
  ansible collection location = /home/zaki/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/zaki/src/ansible-sample/venv/ansible4/bin/ansible
  python version = 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
  jinja version = 3.0.1
  libyaml = True

Towerは3.8.0 (on RHEL8)

zaki-hmkc.hatenablog.com

参考情報

www.ansible.com

docs.ansible.com

コレクションの場合

zaki-hmkc.hatenablog.com


続報に期待です :)
(いつも貴重な情報ありがとうございます!!)