tk_ch’s blog

インフラエンジニアのブログ

Ansibleのベストプラクティスなディレクトリ構成を試す

Ansibleを使用する際に、プレイブックを運用し易く使い勝手のいいものにするためには、ディレクトリ構成が重要。
Ansible公式ドキュメントのSample Ansible setupにベストプラクティスなディレクトリ構成が載っているので、これを試してみる。
本記事で使ったプレイブックはここにある。

環境

Ansibleバージョン

  • ansible:7.3.0
  • ansible-core:2.14.3

※Ansibleの実行環境は以下記事で構築したものを使う。 tk-ch.hatenablog.com

Ansible実行対象のサーバ

商用環境
  • test-prd-001 (192.168.10.1)
  • test-prd-002 (192.168.10.2)
  • test-prd-003 (192.168.10.3)
    ステージング環境
  • test-stg-001 (192.168.20.1)

実施内容

ディレクトリ構成

Ansible公式ドキュメントには、「Sample directory layout」と「Alternative directory layout」の2パターンが載っている。
今回は、環境面(商用環境、ステージング環境など)の差分が大きくても柔軟に対応しやすい後者のパターンを参考にして、以下のような構成とした。

ansible
|-- ansible.cfg                     # Ansibleの設定ファイル
|-- inventories                     # インベントリと変数定義の格納場所
|   |-- production                  # 商用環境用
|   |   |-- group_vars              # グループ単位の変数定義の格納場所
|   |   |   |-- all.yml             # 全グループ共通の変数定義
|   |   |   |-- test_group_a.yml    # グループごとの変数定義(ファイル名はグループ名.yml)
|       |   |-- test_group_ab.yml
|   |   |   `-- test_group_b.yml
|   |   |-- host_vars               # ホスト単位の変数定義の格納場所
|   |   |   |-- test-prd-001.yml    # ホストごとの変数定義(ファイル名はホスト名.yml)
|   |   |   |-- test-prd-002.yml
|   |   |   `-- test-prd-003.yml
|   |   `-- hosts                   # インベントリ(Ansibleの実行対象ホスト、グループの定義)
|   `-- staging                     # ステージング環境用
|       |-- group_vars
|       |   |-- all.yml
|       |   |-- test_group_a.yml
|       |   |-- test_group_ab.yml
|       |   `-- test_group_b.yml
|       |-- host_vars
|       |   `-- test-stg-001.yml
|       `-- hosts
|-- roles                           # タスク定義の格納場所
|   |-- role00                      # ロール単位でタスク定義をまとめている
|   |   |-- defaults
|   |   |   `-- main.yml            # ロールのデフォルト変数定義
|   |   `-- tasks
|   |       `-- main.yml            # タスクで実行したい処理をここに書く
|   |-- role01
|   |   |-- defaults
|   |   |   `-- main.yml
|   |   |-- tasks
|   |   |   `-- main.yml
|   |   |-- templates
|   |   |   `-- variable.txt.j2     # templateモジュールで使うテンプレートファイル
|   |   `-- vars
|   |       `-- main.yml            # ロール変数定義
|   `-- role02
|       |-- defaults
|       |   `-- main.yml
|       |-- tasks
|       |   `-- main.yml
|       |-- templates
|       |   `-- variable.txt.j2
|       `-- vars
|           `-- main.yml
|-- site.yml                        # マスタープレイブック

|-- test_group_a.yml                # 実行対象のグループとロールを記載したプレイブック
`-- test_group_b.yml
構成のポイント
  • タスクをロール単位に分割し、変数やインベントリと分離することで、タスクの再利用性を高めている。
  • 変数とインベントリは環境面ごとにディレクトリを分けることで、環境面同士の差分が大きい場合(サーバの構成や台数が違う、必要な変数定義が異なるなど)でも、柔軟に対応できるようになっている。
  • 小さい実行粒度でまとめたプレイブック(例だとtest_group_a.ymlとtest_group_b.yml)をそれらをまとめて読み込むマスタープレイブック(site.yaml)を用意している。
    これにより、公式ドキュメントのこちらに記載の通り、細かい単位でプレイブックを実行しやすくなる。
    ※ansible-playbook実行時に--limitオプションで実行するロールを指定することもできるが、より明示的で、ロール単位より広い粒度での実行もしやすいという利点がある。
  • Ansible では変数は様々な箇所に定義可能だが、この構成では以下のファイルに定義する。
    ちなみにこれらのファイルに同じ変数が存在する場合、優先度に従い上書きされる(優先度は下に行くほど高い。変数の優先順の詳細はこちらを参照。)
    • roles/ロール名/defaults/main.yml:ロールのデフォルト変数の定義場所。値が環境面やホストによらない変数を定義する。
    • inventories/環境名/group_vars/all.yml:グループ変数の定義場所。ある環境内で、全グループ共通の値になる変数を定義する。
    • inventories/環境名/group_vars/グループ名.yml:グループ変数の定義場所。グループごとに値が異なる変数を定義する。
      グループ間に親子関係がある場合は、親グループ.ymlに定義された変数が子グループに継承される。
      親と子で同じ変数が定義されている場合は、子グループ名.ymlに定義された値の方が変数の優先度が高い。
    • inventories/環境名/hosts_vars/ホスト名.yml:ホスト変数の定義場所。ホストごとに値が異なる変数を定義する。
    • roles/ロール名/vars/main.yml:ロール変数の定義場所。値が環境面やホストによらず、かつグループ変数やホスト変数で上書きされたくない変数を定義する。

各ファイルの内容

上記のディレクトリ構成を試すにあたり、以下が気になっているので確認したい。

  • 商用環境とステージング環境で、同じロールを使いまわせること、結果が環境面ごとの変数に応じて変わること。
  • プレイブックに記載した内容に応じて、適切なホストに適切なロールが実行されること。
  • ロールごと、グループごと、ホストごとに定義した変数が、想定通り読み込まれること。

→上記が確認できるように、以下のような内容でファイルを作成した。

  • グループを2つ(test_group_a、test_group_b)作成し、「test_group_aにはrole00とrole01を実行し、test_group_bにはrole00とrole02を実行する」という違いをつける。
  • 親子グループの挙動も確認したいので、test_group_a、test_group_bを子とする親グループ「test_group_ab」も定義する。
  • group_varsディレクトリ配下のファイルに全グループ共通のグループ変数「test_var_group_all」 、グループごとに値が異なるグループ変数「test_var_group」、グループをまとめた親グループの変数「test_var_group_parent」 を定義する。
  • host_varsディレクトリ配下のファイルに、ホストごとに値が異なるホスト変数「test_var_host 」を定義する。
  • グループ変数とホスト変数の値は、商用環境とステージング環境でも異なる値にする。
  • ロールごとに値が異なるロールのデフォルト変数「test_var_role_default」、ロール変数「test_var_role」を定義する。
  • role02、role03は上記変数をテキストに出力するタスクにして、想定通り変数が読み込まれたことを確認できるようにする。
  • 上記変数は、上書きの優先度が想定通りであることを確認するために、想定される優先度が自分より高いファイルに定義された変数も、併せて定義しておく。
ロール
role00

処理内容は何でもよかったが、タスクの繰り返し実行を書いてみたかったので、複数のサービスの自動起動を有効化する内容にした。
roles/role00/tasks/main.yml

---
- name: enable and start services
  systemd:
    daemon_reload: yes
    enabled: yes
    state: started
    name: "{{ item }}"
  with_items: "{{  role00_services_list  }}"

対象になるサービスのリストを変数として定義している。
roles/role00/defaults/main.yml

---
role00_services_list:
  - chronyd
  - crond
  - sshd
role01

今回定義した変数が書き込まれるテキストファイルを、templateモジュールで作成する内容。
roles/role01/tasks/main.yml

---
- name: "create {{ role_name }} variable test file"
  template:
    src: variable.txt.j2
    dest: "/tmp/{{ role_name }}.txt"

ロールのデフォルト変数の定義。
「test_var_role_default」以外は他の箇所に定義された値に上書きされる想定。
roles/role01/defaults/main.yml

---
test_var_role_default: "roles/role01/defaults/main.yml"
test_var_group_all: "roles/role01/defaults/main.yml"
test_var_group_parent: "roles/role01/defaults/main.yml"
test_var_group: "roles/role01/defaults/main.yml"
test_var_host: "roles/role01/defaults/main.yml"
test_var_role: "roles/role01/defaults/main.yml"

ロール変数。
roles/role01/vars/main.yml

---
test_var_role: "roles/role01/vars/main.yml"

変数を書き込むテキストファイルのテンプレート。
roles/role01/templates/variable.txt.j2

test_var_role_default: {{ test_var_role_default }}
test_var_group_all   : {{ test_var_group_all }}
test_var_group_parent: {{ test_var_group_parent }}
test_var_group       : {{ test_var_group }}
test_var_host        : {{ test_var_host }}
test_var_role        : {{ test_var_role }}
role02

role01と同様の処理で、以下の変数の値のみ変更した内容。
roles/role02/defaults/main.yml

---
test_var_role_default: "roles/role02/defaults/main.yml"
test_var_group_all: "roles/role02/defaults/main.yml"
test_var_group_parent: "roles/role02/defaults/main.yml"
test_var_group: "roles/role02/defaults/main.yml"
test_var_host: "roles/role02/defaults/main.yml"
test_var_role: "roles/role02/defaults/main.yml"

roles/role02/vars/main.yml

---
test_var_role: "roles/role02/vars/main.yml"
環境面ごとのインベントリ・変数定義
商用環境(production)

実行対象のホスト名を記載している。
※ホスト名指定でSSHできない環境なので、ここで紹介されているようにマジック変数である「ansible_host」にIPを設定している。
 IP自体をホスト名として記載しても接続はできるが、ホスト名とIPが両方記載されている方が分かりやすいと思うので、この書き方にした。 inventories/production/hosts

[test_group_a]
test-prd-001 ansible_host=192.168.10.1
test-prd-002 ansible_host=192.168.10.2

[test_group_b]
test-prd-003 ansible_host=192.168.10.3

[test_group_ab:children]
test_group_a
test_group_b

全グループ共通の値になるグループ変数の定義。
「test_var_group_all」以外は他の箇所に定義された値に上書きされる想定。
Ansibleは、実行対象のサーバに対し鍵認証でSSHすることを推奨しているが、今回使っているサーバはパスワード認証であるため、「ansible_ssh_user」、「ansible_ssh_pass」を設定している。
不要な場合は削除すること。
inventories/production/group_vars/all.yml

---
ansible_ssh_user: root
ansible_ssh_pass: password
test_var_group_all: "inventories/production/group_vars/all.yml"
test_var_group_parent: "inventories/production/group_vars/all.yml"
test_var_group: "inventories/production/group_vars/all.yml"
test_var_host: "inventories/production/group_vars/all.yml"
test_var_role: "inventories/production/group_vars/all.yml"

グループ名.ymlという名前のファイルに、グループごとに値が異なるグループ変数を定義する。
まずは親グループ。
「test_var_group_parent」以外は他の箇所に定義された値に上書きされる想定。
inventories/production/group_vars/test_group_ab.yml

---
test_var_group_parent: "inventories/production/group_vars/test_group_ab.yml"
test_var_group: "inventories/production/group_vars/test_group_ab.yml"
test_var_host: "inventories/production/group_vars/test_group_ab.yml"
test_var_role: "inventories/production/group_vars/test_group_ab.yml"

次に子グループ。
「test_var_group」以外は他の箇所に定義された値に上書きされる想定。
inventories/production/group_vars/test_group_a.yml

---
test_var_group: "inventories/production/group_vars/test_group_a.yml"
test_var_host: "inventories/production/group_vars/test_group_a.yml"
test_var_role: "inventories/production/group_vars/test_group_a.yml"

inventories/production/group_vars/test_group_b.yml

---
test_var_group: "inventories/production/group_vars/test_group_b.yml"
test_var_host: "inventories/production/group_vars/test_group_b.yml"
test_var_role: "inventories/production/group_vars/test_group_b.yml"

ホスト名.ymlという名前のファイルに、ホストごとに値が異なるグループ変数を定義する。 「test_var_role」は「roles/ロール名/defaults/main.yml」に定義された値に上書きされる想定。
inventories/production/host_vars/test-prd-001.yml

---
test_var_host: "inventories/production/host_vars/test-prd-001.yml"
test_var_role: "inventories/production/host_vars/test-prd-001.yml"

inventories/production/host_vars/test-prd-002.yml

---
test_var_host: "inventories/production/host_vars/test-prd-002.yml"
test_var_role: "inventories/production/host_vars/test-prd-002.yml"

inventories/production/host_vars/test-prd-003.yml

---
test_var_host: "inventories/production/host_vars/test-prd-003.yml"
test_var_role: "inventories/production/host_vars/test-prd-003.yml"
ステージング環境(staging)

商用環境とほぼ同様の構成。
実行対象サーバが少ないのと、変数に設定された値が商用環境と異なる。
inventories/staging/hosts

[test_group_a]
test-stg-001 ansible_host=192.168.20.1

[test_group_b]

[test_group_ab:children]
test_group_a
test_group_b

inventories/staging/group_vars/all.yml

---
ansible_ssh_user: root
ansible_ssh_pass: password
test_var_group_all: "inventories/staging/group_vars/all.yml"
test_var_group_parent: "inventories/staging/group_vars/all.yml"
test_var_group: "inventories/staging/group_vars/all.yml"
test_var_host: "inventories/staging/group_vars/all.yml"
test_var_role: "inventories/staging/group_vars/all.yml"

inventories/staging/group_vars/test_group_ab.yml

---
test_var_group_parent: "inventories/staging/group_vars/test_group_ab.yml"
test_var_group: "inventories/staging/group_vars/test_group_ab.yml"
test_var_host: "inventories/staging/group_vars/test_group_ab.yml"
test_var_role: "inventories/staging/group_vars/test_group_ab.yml"

inventories/staging/group_vars/test_group_a.yml

---
test_var_group: "inventories/staging/group_vars/test_group_a.yml"
test_var_host: "inventories/staging/group_vars/test_group_a.yml"
test_var_role: "inventories/staging/group_vars/test_group_a.yml"

inventories/staging/group_vars/test_group_b.yml

---
test_var_group: "inventories/staging/group_vars/test_group_b.yml"
test_var_host: "inventories/staging/group_vars/test_group_b.yml"
test_var_role: "inventories/staging/group_vars/test_group_b.yml"

inventories/staging/host_vars/test-stg-001.yml

---
test_var_host: "inventories/staging/host_vars/test-stg-001.yml"
test_var_role: "inventories/staging/host_vars/test-stg-001.yml"
プレイブック

test_group_aグループにrole00とrole01を実行するという内容。
ロールにタグをつけておくと、一部のロールだけ実行することができ便利なので、こちらを参考タグを設定した。
test_group_a.yml

---
- name: test_group_a
  hosts: test_group_a
  roles:
    - role: role00
      tags: role00
    - role: role01
      tags: role01

こちらはtest_group_bグループにrole00とrole02を実行するという内容。
test_group_b.yml

---
- name: test_group_b
  hosts: test_group_b
  roles:
    - role: role00
      tags: role00
    - role: role02
      tags: role02

マスタープレイブック。
上記2つのプレイブックをimportする。
site.yml

- import_playbook: test_group_a.yml
- import_playbook: test_group_b.yml

親グループをプレイブックのhostsに指定した場合の挙動についても確認したいため、親グループtest_group_abにrole00とrole01を実行するという内容のプレイブックも用意する。
test_group_ab.yml

---
- name: test_group_ab
  hosts: test_group_ab
  roles:
    - role: role00
      tags: role00
    - role: role01
      tags: role01
Ansibleの設定ファイル

ansible.cfgに変数を設定することで、Ansibleの挙動を制御できる。
今回は、ホストへの初回のSSH接続の際に出る警告を無視するために「host_key_checking = False」を設定した。
他の設定値はAnsible Configuration Settingsを参照。
ansible.cfg

[defaults]
host_key_checking = False

実行してみる

まず、商用環境に対して実行する。
実行対象の環境の制御は、以下のようにansible-playbook実行時に-iオプションで指定するインベントリファイルを使い分けることで実現する。

$ ansible-playbook -i inventories/production/hosts site.yml

PLAY [test_group_a] ******************************************************************************************

TASK [Gathering Facts] ***************************************************************************************
ok: [test-prd-001]
ok: [test-prd-002]

TASK [role00 : enable and start services] ********************************************************************
ok: [test-prd-001] => (item=chronyd)
ok: [test-prd-002] => (item=chronyd)
ok: [test-prd-001] => (item=crond)
ok: [test-prd-002] => (item=crond)
ok: [test-prd-001] => (item=sshd)
ok: [test-prd-002] => (item=sshd)

TASK [role01 : create role01 variable test file] *************************************************************
changed: [test-prd-001]
changed: [test-prd-002]

PLAY [test_group_b] ******************************************************************************************

TASK [Gathering Facts] ***************************************************************************************
ok: [test-prd-003]

TASK [role00 : enable and start services] ********************************************************************
ok: [test-prd-003] => (item=chronyd)
ok: [test-prd-003] => (item=crond)
ok: [test-prd-003] => (item=sshd)

TASK [role02 : create role02 variable test file] *************************************************************
changed: [test-prd-003]

PLAY RECAP ***************************************************************************************************
test-prd-001               : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
test-prd-002               : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
test-prd-003               : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

→プレイブックに記載した通り、test_group_aにはrole00とrole01、test_group_bにはrole00とrole02が実行された。  
role01、role02で作成されたファイルは以下の通り。
test-prd-001の/tmp/role01.txt

test_var_role_default: roles/role01/defaults/main.yml
test_var_group_all   : inventories/production/group_vars/all.yml
test_var_group_parent: inventories/production/group_vars/test_group_ab.yml
test_var_group       : inventories/production/group_vars/test_group_a.yml
test_var_host        : inventories/production/host_vars/test-prd-001.yml
test_var_role        : roles/role01/vars/main.yml

test-prd-002の/tmp/role01.txt

test_var_role_default: roles/role01/defaults/main.yml
test_var_group_all   : inventories/production/group_vars/all.yml
test_var_group_parent: inventories/production/group_vars/test_group_ab.yml
test_var_group       : inventories/production/group_vars/test_group_a.yml
test_var_host        : inventories/production/host_vars/test-prd-002.yml
test_var_role        : roles/role01/vars/main.yml

test-prd-003の/tmp/role02.txt

test_var_role_default: roles/role02/defaults/main.yml
test_var_group_all   : inventories/production/group_vars/all.yml
test_var_group_parent: inventories/production/group_vars/test_group_ab.yml
test_var_group       : inventories/production/group_vars/test_group_b.yml
test_var_host        : inventories/production/host_vars/test-prd-003.yml
test_var_role        : roles/role02/vars/main.yml

→内容を比較すると、想定通り以下の挙動となっていることが分かる。

  • all_varsは全て同じ値。
    「roles/ロール名/defaults/main.yml」で定義された値が、「inventories/production/group_vars/all.yml」で定義された値で上書きされている。
  • test_var_group_parentの値はインベントリで定義された親グループから継承されている。
    「roles/ロール名/defaults/main.yml」で定義された値が、「inventories/production/group_vars/親グループ名.yml」で定義された値で上書きされている。
  • group_varsはグループごとに異なる値。
    「roles/ロール名/defaults/main.yml」、「inventories/production/group_vars/all.yml」で定義された値が、「inventories/production/group_vars/グループ名.yml」で定義された値で上書きされている。
  • host_varsはホストごとに異なる値。
    「roles/ロール名/defaults/main.yml」、「inventories/production/group_vars/all.yml」、「inventories/production/group_vars/グループ名.yml」で定義された値が、「inventories/production/group_vars/ホスト名.yml」で定義された値で上書きされている。
  • role_varsはロールごとに異なる値。
    「roles/ロール名/defaults/main.yml」、「inventories/production/group_vars/all.yml」、「inventories/production/group_vars/グループ名.yml」、「inventories/production/group_vars/ホスト名.yml」で定義された値が、「roles/ロール名/vars/main.yml」で定義された値で上書きされている。

次に、ステージング環境に対して実行する。

$ ansible-playbook -i inventories/staging/hosts site.yml

PLAY [test_group_a] ******************************************************************************************

TASK [Gathering Facts] ***************************************************************************************
ok: [test-stg-001]

TASK [role00 : enable and start services] ********************************************************************
ok: [test-stg-001] => (item=chronyd)
ok: [test-stg-001] => (item=crond)
ok: [test-stg-001] => (item=sshd)

TASK [role01 : create role01 variable test file] *************************************************************
changed: [test-stg-001]

PLAY [test_group_b] ******************************************************************************************
skipping: no hosts matched

PLAY RECAP ***************************************************************************************************
test-stg-001               : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

→ansible-paybook実行時に指定するインベントリファイルを変更することで、実行先が切り替わったことが分かる。
 
role01で作成されたファイルは以下の通り。
test-stg-001の/tmp/role01.txt

test_var_role_default: roles/role01/defaults/main.yml
test_var_group_all   : inventories/staging/group_vars/all.yml
test_var_group_parent: inventories/staging/group_vars/test_group_ab.yml
test_var_group       : inventories/staging/group_vars/test_group_a.yml
test_var_host        : inventories/staging/host_vars/test-stg-001.yml
test_var_role        : roles/role01/vars/main.yml

→商用環境のtest-prd-001の/tmp/role01.txtと比較すると、想定通り値がproductionからstagingに変わっていることが分かる。

プレイブックのhostsに親グループを指定した場合

プレイブックのhostsに子グループを指定して実行した場合に、group_vars/子グループ名.ymlとgroup_vars/親グループ名.ymlのどちらで定義された変数も読み込まれていることは確認できた。
プレイブックのhostsに親グループを指定して実行した場合の挙動も確認しておく。
親グループをhostsに指定したプレイブックを実行する。

# ansible-playbook -i inventories/production/hosts test_group_ab.yml

PLAY [test_group_ab] ********************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [192.168.10.1]
ok: [192.168.10.2]
ok: [192.168.10.3]

TASK [role00 : enable and start services] ***********************************************************************
ok: [192.168.10.1] => (item=chronyd)
ok: [192.168.10.2] => (item=chronyd)
ok: [192.168.10.3] => (item=chronyd)
ok: [192.168.10.1] => (item=crond)
ok: [192.168.10.2] => (item=crond)
ok: [192.168.10.1] => (item=sshd)
ok: [192.168.10.2] => (item=sshd)
ok: [192.168.10.3] => (item=crond)
ok: [192.168.10.3] => (item=sshd)

TASK [role01 : create role01 variable test file] ****************************************************************
ok: [192.168.10.2]
ok: [192.168.10.1]
changed: [192.168.10.3]

PLAY RECAP ******************************************************************************************************
192.168.10.3               : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.10.1               : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.10.2               : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

role01で作成されたファイルの内容は以下の通り。
test-prd-001の/tmp/role01.txt

test_var_role_default: roles/role01/defaults/main.yml
test_var_group_all   : inventories/production/group_vars/all.yml
test_var_group_parent: inventories/production/group_vars/test_group_ab.yml
test_var_group       : inventories/production/group_vars/test_group_a.yml
test_var_host        : inventories/production/host_vars/test-prd-001.yml
test_var_role        : roles/role01/vars/main.yml

test-prd-002の/tmp/role01.txt

test_var_role_default: roles/role01/defaults/main.yml
test_var_group_all   : inventories/production/group_vars/all.yml
test_var_group_parent: inventories/production/group_vars/test_group_ab.yml
test_var_group       : inventories/production/group_vars/test_group_a.yml
test_var_host        : inventories/production/host_vars/test-prd-002.yml
test_var_role        : roles/role01/vars/main.yml

test-prd-003の/tmp/role01.txt

test_var_role_default: roles/role01/defaults/main.yml
test_var_group_all   : inventories/production/group_vars/all.yml
test_var_group_parent: inventories/production/group_vars/test_group_ab.yml
test_var_group       : inventories/production/group_vars/test_group_b.yml
test_var_host        : inventories/production/host_vars/test-prd-003.yml
test_var_role        : roles/role01/vars/main.yml

→hostsに子グループを指定したときと同様の内容となっている。
このことから、プレイブックのhostsに親子どちらのグループを記載しても、group_vars/子グループ名.ymlとgroup_vars/親グループ名.ymlの両方が読み込まれていることが分かる。

タグを使って指定したロールだけを実行する

おまけとして、タグを使った一部ロールの実行も試してみる。
ansible-playbook実行時に、「--tags タグ名」オプションを付けることでタグが一致するロールのみが実行される。

$ ansible-playbook -i inventories/production/hosts --tags role00 site.yml

PLAY [test_group_a] *********************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [test-prd-001]
ok: [test-prd-002]

TASK [role00 : enable and start services] ***********************************************************************
ok: [test-prd-002] => (item=chronyd)
ok: [test-prd-001] => (item=chronyd)
ok: [test-prd-001] => (item=crond)
ok: [test-prd-002] => (item=crond)
ok: [test-prd-002] => (item=sshd)
ok: [test-prd-001] => (item=sshd)

PLAY [test_group_b] *********************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [test-prd-003]

TASK [role00 : enable and start services] ***********************************************************************
ok: [test-prd-003] => (item=chronyd)
ok: [test-prd-003] => (item=crond)
ok: [test-prd-003] => (item=sshd)

PLAY RECAP ******************************************************************************************************
test-prd-001               : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
test-prd-002               : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
test-prd-003               : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

→想定通り、role00だけが実行された。

まとめ

  • ベストプラクティスを意識したディレクトリ構成にすることで、環境差分を吸収してロールの再利用性を高めることができた。
  • 各種変数の定義場所、上書き優先度を確認できた。

参考文献