てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] ロールの vars や defaults 配下の main.yml は「main ディレクトリ」でもいい

はじめに

Ansible のロールでは、ロールの変数を vars/main.yml に、デフォルト値を defaults/main.yml定義するというのが基本的なディレクトリ、ファイル構造です。

いつのバージョンからかはわかりませんが、それぞれ main.yml ではなくて main ディレクトリを用意して、その中に複数ファイルを入れておく構造でも読み取ってくれます。 この仕様が最近ドキュメントに明記されました。

Directories defaults and vars may also include nested directories.

Roles — Ansible Community Documentation

私がこの仕様を知ったのもこのプルリクでした。へ〜と思ったので試してみました。

  • 検証環境
    • ansible-core 2.12.0
    • ansible-core 2.16.2

お試し

以下のファイル構成で試します。main.yml ではなく、main ディレクトリなところがポイントです。

.
├── playbook.yml
└── roles
    └── myrole
        ├── defaults
        │   └── main
        │       ├── defaults01.yml
        │       └── defaults02.yml
        ├── tasks
        │   └── main.yml
        └── vars
            └── main
                ├── vars01.yml
                └── vars02.yml

ロールの各種ファイルの準備

myrole ロールとして、varsdefaults 変数定義、タスクの定義します。

defaults

roles/myrole/defaults/main/defaults01.yml:

---
defaults01_var: var in defaults/main/default01.yml

roles/myrole/defaults/main/defaults02.yml:

---
defaults02_var: var in defaults/main/default02.yml

vars

roles/myrole/vars/main/vars01.yml:

---
vars01_var: var in vars/main/vars01.yml

roles/myrole/vars/main/vars02.yml:

---
vars02_var: var in vars/main/vars02.yml

tasks

ここまで定義してきた変数をただ表示するだけです。

roles/myrole/tasks/main.yml:

---
- name: Test Debug
  ansible.builtin.debug:
    msg: 
      - "{{ vars01_var }}"
      - "{{ vars02_var }}"
      - "{{ defaults01_var }}"
      - "{{ defaults02_var }}"

Playbookの準備

ロールを呼び出す Playbook 側です。

---
- hosts: localhost
  gather_facts: false

  tasks:
    - name: Role Test
      ansible.builtin.import_role:
        name: myrole

Playbook の実行

それでは Playbook を実行します。

% ansible-playbook -i localhost, playbook.yml

PLAY [localhost] *****************************************************************************************************

TASK [myrole : Test Debug] ******************************************************************************************
ok: [localhost] => {
    "msg": [
        "var in vars/main/vars01.yml",
        "var in vars/main/vars02.yml",
        "var in defaults/main/default01.yml",
        "var in defaults/main/default02.yml"
    ]
}

PLAY RECAP ***********************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

想定通り vars/main ディレクトリや defaults/main ディレクトリ内で定義した変数の値が表示されました。

おわりに

インベントリ変数でいう group_vars/グループ名.yml だけでなく group_vars/グループ名/*.yml も、host_vars/ホスト名.yml だけでなく host_vars/ホスト名/*.yml でも読み込んでくれる仕様と似ているなと思いました。