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
実装例は以下。
サンプル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のリポジトリ
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
記事を拝見しました!
— xotaki (@xotaki) 2021年8月19日
ここに書いていない内容でちょっとした tips は、2回目以降のダウンロードのとき(上書きしたい場合)は、 -f オプションを指定します。
使っていると欲しくなるオプションです :-)
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の内容は更新されなかった。
— すぎむら (@sugitk) 2021年8月19日
これはプロジェクトで「起動時のリビジョン更新」のオプションを有効にするとどうでしょう。
ジョブを実行したときのログはこの通りで、指定の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)
参考情報
■Ansible Towerの場合
— えんでぃ (@stopendy0122) 2021年2月10日
roles/requirements.yml をPlaybookと同じディレクトリに置いておきます。
requirements.ymlにはGitLabなどのURL、欲しいroleとそのバージョンを記載します。
Ansible TowerがPlaybookを読み込む度にrequirements.ymlに従ってroleをPull することで、roleが共有されます。
コレクションの場合
続報に期待です :)
(いつも貴重な情報ありがとうございます!!)
赤帽エンジニアブログで説明しますかー
— すぎむら (@sugitk) 2021年8月19日
そのへんややこしいですよね