作業環境
- CentOS 8.0
- Python 3.7.7
- Ansible 2.9.6
Role とは
Ansible における Role とは:
- Playbook に読み込まれて実行されるタスクリストの拡張版のようなもの
- Role の構成要素として以下がある
- タスク
- 変数
- コンフィグファイル、テンプレートファイル
- ハンドラ
- メタ情報
- Role は以下の様なディレクトリ構造で作成する(ベストプラクティスによる)
roles/ <--- Role を格納するディレクトリ
role_01/ <--- 一つの Role (role_01 という名前)のディレクトリ
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
項番 | 要素 | 格納 ディレクトリ | ファイル名 | 説明 |
1 | 各種ファイル | files/ | 任意 | copy モジュールで使用されるファイル |
2 | テンプレート | templates/ | 任意 | template モジュールで使用されるファイル |
3 | タスクファイル | tasks/ | main.yml | 実行されるタスクを記したファイル |
4 | ハンドラ | handlers/ | main.yml | ハンドラ(notify: で使用するタスクを記載) |
5 | 変数ファイル | vars/ | main.yml | 最も優先される変数ファイル |
6 | 変数ファイル | defaults/ | main.yml | デフォルトの変数ファイル |
7 | メタ情報 | meta/ | main.yml | Role の依存関係を記載したファイル |
上記の Role を構成するディレクトリの内少なくともどれか一つは作成する必要がありますが、使用しないディレクトリは作成しなくても問題ありません。
Playbook への Role の読み込み
Role を Playbook へ読み込む方法としては以下があります。
- roles: オプションを使用する
- include_role モジュールを使用する
- import_role モジュールを使用する
roles: オプションを使用する場合
Playbook の中で以下のように roles: オプションの値に Role 名を指定します。
- hosts: all
roles:
- role_name
ここで、Playbook と Role を格納する Roles ディレクトリの位置関係によって Role 名の指定方法が異なります。
Playbook と Roles ディレクトリが同じディレクトリに存在する場合
以下のディレクトリ構造だとします。
playbook.yml
Roles/
role_01/
...
この場合には、以下のように単に Role 名(Role のディレクトリ名)だけを指定します。
- hosts: all
roles:
- role_01
Playbook と Roles ディレクトリが異なるディレクトリに存在する場合
以下のディレクトリ構造だとします。
playbook.yml
dir/
Roles/
role_01/
...
この場合には、以下のように Role のディレクトリのパスを指定します。
- hosts: all
roles:
- dir/roles/role_01
include_role モジュールを使用する場合
include_role モジュールを使用する場合は、Plybook の tasks: オプションのタスクとして以下のように記載します。
- hosts: all
become: yes
tasks:
- name: include role
include_role:
name: role_name
include_role の name: パラメータで Role を指定します。
Role の指定方法は roles: オプションを使用する場合と同じです。
import_role モジュールを使用する場合
import_role モジュールの使い方は include_role モジュールと同じです。
import_role と include_role の違いは、import_role は静的処理で include_role は動的処理という点ですが、ここでは詳細は省略します。
roles: と tasks: の実行順序
roles: オプションと tasks: オプションの両方を Playbook に記載した場合、まず roles: オプションに記載した Role が実行され、その後で tasks: オプションに記載したタスクが実行されます。
Role 使用例
変数 message の内容を debug モジュールで出力するタスクを実行する Role「test」を Playbook に読み込んで実行してみます。
- include_role モジュールで Role を読み込むことにします
- 「test」 Role の構成要素として、タスクファイルと変数ファイル(defaults)を作成することにします
■ ディレクトリ構造
$ tree --charset c
.
|-- hosts
|-- playbook.yml
`-- roles
`-- test
|-- defaults
| `-- main.yml
`-- tasks
`-- main.yml
■ playbook.yml
- hosts: all
tasks:
- name: include role
include_role:
name: test
■ roles/test/tasks/main.yml
- name: msg
debug:
msg: '{{ message }}'
■ roles/test/defaults/main.yml
message: 'message in defaults'
■ Ansible 実行結果
$ ansible-playbook -i hosts playbook.yml
PLAY [all] **********************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************
ok: [10.69.34.57]
TASK [include role] *************************************************************************************************
TASK [test : msg] ***************************************************************************************************
ok: [10.69.34.57] => {
"msg": "message in defaults"
}
PLAY RECAP **********************************************************************************************************
10.69.34.57 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Role における変数の優先順位
Role のタスク内で変数を使用する場合、変数を定義する場所として以下が考えられます。
- Role の /(Role)/defaults/main.yml で定義する
- Role の /(Role)/vars/main.yml で定義する
- Playbook の vars: オプションで定義する
同じ名前の変数が上の内の複数個所で定義されていて、変数の値が異なっている場合、どこで定義された値が優先されて使用されるか、という優先順位については以下の順になります。
- Role の /(Role)/vars/main.yml
- Playbook の vars: オプション
- Role の /(Role)/defaults/main.yml
【参考】公式ドキュメント
―――――――――――――