サーバーの構築で共通する設定作業などを、 Ansible Collection で再利用できるようにしておくと便利ですね。
詳しい情報が公式ドキュメントに載っていますので、これを見ながら実際に試してみた(そして躓いた)手順を記録しておきます。
collection を作る
ansible-galaxy collection init
のコマンドで空 (skelton) の collection を作ることができます。
ここでは、 thisis
という namespace に example
という名前のロールを作ってみます。
% ansible-galaxy collection init thisis.example
- Collection thisis.example was created successfully
% find .
.
./thisis
./thisis/example
./thisis/example/plugins
./thisis/example/plugins/README.md
./thisis/example/roles
./thisis/example/docs
./thisis/example/README.md
./thisis/example/galaxy.yml
ぱっと見で分かる通り、 collection を作るには正しいディレクトリ構成と galaxy.yml
があればOKです。
この galaxy.yml
のファイルに collection のメタ情報を記載します。
ansible-galaxy init collection
の実行直後では、以下の様なデフォルト値が設定されています。
% grep '^[^#]' thisis/example/galaxy.yml
namespace: thisis
name: example
version: 1.0.0
readme: README.md
authors:
- your name <example@domain.com>
description: your collection description
license:
- GPL-2.0-or-later
license_file: ''
tags: []
dependencies: {}
repository: http://example.com/repository
documentation: http://docs.example.com
homepage: http://example.com
issues: http://example.com/issue/tracker
build_ignore: []
上記で必須の設定は authors
より上だけなので、必要な情報を集めて適宜編集します。
galaxy.yml
が準備できたら、共有したい作業などを roles/
以下に用意しましょう。
% mkdir -p thisis/example/roles/aaa/tasks/
% echo <<EOL > thisis/example/roles/aaa/tasks/main.yml
heredoc> ---
heredoc> - name: aaa
heredoc> debug:
heredoc> msg: 問題なし!OK!
heredoc>
heredoc> EOL
ここまでできたら、あとは exapmle
のディレクトリを適当な git repo として push すれば作成完了です。
collection を使ってみる
collection を使いたい playbook の requirements.yml
で、使用したい collection (==先ほど作成したもの)を指定します。
git repo へのアクセスに ssh 認証が必要でしたら、以下の様に git+ssh://git@~
の形式で name
を指定します。
% cat requirements.yml
collections:
- name: git+ssh://git@your-git-host.com/your-org/ansible-collection-example.git
type: git
version: main
上記を用意して ansible-galaxy install -r requirements.yml
を実行すると、ホストの ANSIBLE_COLLECTIONS_PATHS
(デフォルトだと ~/.ansible/collections/
配下)に role がインストールされます。
% ansible-galaxy install -r requirements.yml
Starting galaxy collection install process
Process install dependency map
Cloning into '/Users/whoami/.ansible/tmp/(略)/ansible-collection-examplexxxxxx'...
remote: Enumerating objects: 24, done.
remote: Counting objects: 100% (11/11), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 24 (delta 1), reused 0 (delta 0), pack-reused 13
Receiving objects: 100% (24/24), done.
Resolving deltas: 100% (1/1), done.
Already on 'main'
Your branch is up to date with 'origin/main'.
Starting collection install process
Installing 'thisis.example:1.0.0' to '/Users/whoami/.ansible/collections/ansible_collections/thisis/example'
Created collection for thisis.example:1.0.0 at /Users/whoami/.ansible/collections/ansible_collections/thisis/example
thisis.example:1.0.0 was installed successfully
ここまでできたら、 playbook でロールを指定して実行することができます。
% find .
.
./inventory
./playbook.yml
./requirements.yml
% cat playbook.yml
- hosts: all
roles:
- thisis.example.aaa
% ansible-playbook -i inventory playbook.yml
PLAY [all] **********************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************
ok: [targethost]
TASK [thisis.example.aaa : aaa] *************************************************************************************
ok: [targethost] => {
"msg": "問題なし!OK!"
}
PLAY RECAP **********************************************************************************************************
targethost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
余談: 躓いたこと
ここまでに書いてきた通り、 collection を作るには galaxy.yml
と共有したいロールの実体、それらを内包するディレクトリ構成が必要です。
やろうと思えば、自分でディレクトリを用意して、 galaxy.yml
に必須パラメータ namespace
name
version
readme
authors
だけを記載することで collection を作ることもできます。(実際、自分も最初はそれで試しました。)
ここで注意が必要なのは、 namespace
と name
には使用できる文字が制限されている、ということです。
使用できる文字は [a-zA-Z0-9_]
のいずれかであり、 -
などは使用できません。(自動生成された galaxy.yml
のコメントにもその旨が記載されています)
万が一 namespace
や name
に -
が含まれていると、 ansible-galaxy install -r requirements.yml
でのインストールこそ成功しますが、 playbook の実行時にエラーになってしまいます。
(↓ インストールは成功するが)
% ansible-galaxy install -r requirements.yml
Starting galaxy collection install process
Process install dependency map
Cloning into '/Users/whoami/.ansible/tmp/(略)/ansible-collection-examplexxxxxx'...
remote: Enumerating objects: 31, done.
remote: Counting objects: 100% (18/18), done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 31 (delta 2), reused 0 (delta 0), pack-reused 13
Receiving objects: 100% (31/31), 4.40 KiB | 1.46 MiB/s, done.
Resolving deltas: 100% (2/2), done.
Already on 'main'
Your branch is up to date with 'origin/main'.
Starting collection install process
Installing 'thisis.ex-am-ple:1.0.0' to '/Users/whoami/.ansible/collections/ansible_collections/thisis/ex-am-ple'
Created collection for thisis.ex-am-ple:1.0.0 at /Users/whoami/.ansible/collections/ansible_collections/thisis/ex-am-ple
thisis.ex-am-ple:1.0.0 was installed successfully
(↓ 実行時にエラー(ロールが見つからない旨)になる様子)
% cat playbook.yml
- hosts: all
roles:
- thisis.ex-am-ple.aaa
% ansible-playbook -i inventory playbook.yml
ERROR! the role 'thisis.ex-am-ple.aaa' was not found in /Users/whoami/tmp/roles:/Users/whoami/.ansible/roles:/Users/whoami/tmp
The error appears to be in '/Users/whoami/tmp/playbook.yml': line 4, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
roles:
- thisis.ex-am-ple.aaa
^ here
上記の「ロールが見つからない」というエラーメッセージをそのまま受け取ってしまうと、色々と調査した結果、時間を無駄に浪費してしまうことになります(経験済)。
この命名の制限についてはちゃんと Ansible のドキュメント(または以前から出ている警告メッセージ)を読んでいれば認識できますし、あるいは一番最初に ansible-galaxy collection init
で skelton を作成すれば、コマンド自体がエラーになるので気付くことができます。
% ansible-galaxy collection init thisis.ex-am-ple
ERROR! Invalid collection name 'thisis.ex-am-ple', name must be in the format <namespace>.<collection>.
Please make sure namespace and collection name contains characters from [a-zA-Z0-9_] only.
というわけで、公式の情報をちゃんと読むことは大事ですね。皆さんもお気をつけ下さい。