インベントリの分割

アドホックコマンドの 「インベントリの作成」で使用したインベントは 1 つのインベントリファイルで構成されました。「ロール」でプレイを機能単位に分割したように、インベントリもその内容で複数のファイルに分割し、所定のディレクトリに配置できます。分割したファイルはロールと同じように、他のインベントリの部品として使用できます。


ディレクトリ構造

以下はAnsible の Best Practices で提示されているディレクトリレイアウトです。網掛けがインベントリに関する部分です。

production                # inventory file for production servers
staging                   # inventory file for staging environment

group_vars/
   group1.yml             # here we assign variables to particular groups
   group2.yml
host_vars/
   hostname1.yml          # here we assign variables to particular systems
   hostname2.yml

library/                  # if any custom modules, put them here (optional)
module_utils/             # if any custom module_utils to support modules, put them here (optional)
filter_plugins/           # if any custom filter plugins, put them here (optional)

site.yml                  # master playbook
webservers.yml            # playbook for webserver tier
dbservers.yml             # playbook for dbserver tier

roles/
    common/               # this hierarchy represents a "role"
        tasks/            #
            main.yml      #  <-- tasks file can include smaller files if warranted
        handlers/         #
            main.yml      #  <-- handlers file
        templates/        #  <-- files for use with the template resource
            ntp.conf.j2   #  <------- templates end in .j2
        files/            #
            bar.txt       #  <-- files for use with the copy resource
            foo.sh        #  <-- script files for use with the script resource
        vars/             #
            main.yml      #  <-- variables associated with this role
        defaults/         #
            main.yml      #  <-- default lower priority variables for this role
        meta/             #
            main.yml      #  <-- role dependencies
        library/          # roles can also include custom modules
        module_utils/     # roles can also include custom module_utils
        lookup_plugins/   # or other types of plugins, like lookup in this case

    webtier/              # same kind of structure as "common" was above, done for the webtier role
    monitoring/           # ""
    fooapp/               # ""

インベントリに関する部分の抜粋です。

production                # inventory file for production servers
staging                   # inventory file for staging environment

group_vars/
   group1.yml             # here we assign variables to particular groups
   group2.yml
host_vars/
   hostname1.yml          # here we assign variables to particular systems
   hostname2.yml

productionファイルとstagingファイルがインベントリファイルです。このワークブックはhosts.ymlファイルを使用しています。


group_vars ディレクトリと host_vars ディレクトリ

インベントリファイルの分割後のファイルはgroup_varsディレクトリとhost_varsディレクトリに配置します。

group_vars ディレクトリ
  • グループ全体に適用する変数を定義します。
  • 定義した変数を「グループ変数」と呼びます。
  • グループ名をファイル名にします。
host_vars ディレクトリ
  • ホストだけに適用する(ホスト固有の)変数を定義します。
  • 定義した変数を「ホスト変数」と呼びます。
  • インベントリ内のホスト名をファイル名にします。

重要

group_varsディレクトリとhost_varsディレクトリはインベントリファイルと同じディレクトリ内に作成しなければなりません。

下記のインベントリファイルhosts.ymlを分割します。

---
all:
  vars:
    ansible_user: vagrant
  hosts:
    node1:
      ansible_host: 192.168.1.161
      ansible_ssh_private_key_file: ~/.ssh/node1_key
      stage: prod
  children:
    web:
      vars:
        stage: dev
      hosts:
        node2:
          ansible_host: 192.168.1.162
          ansible_ssh_private_key_file: ~/.ssh/node2_key
        node3:
          ansible_host: 192.168.1.163
          ansible_ssh_private_key_file: ~/.ssh/node3_key

ansible-inventoryコマンドで状態を確認します。

[vagrant@ansible ansible-files]$ ansible-inventory -i hosts.yml --list --yaml
all:
  children:
    ungrouped:
      hosts:
        node1:
          ansible_host: 192.168.1.161
          ansible_ssh_private_key_file: ~/.ssh/node1_key
          ansible_user: vagrant
          stage: prod
    web:
      hosts:
        node2:
          ansible_host: 192.168.1.162
          ansible_ssh_private_key_file: ~/.ssh/node2_key
          ansible_user: vagrant
          stage: dev
        node3:
          ansible_host: 192.168.1.163
          ansible_ssh_private_key_file: ~/.ssh/node3_key
          ansible_user: vagrant
          stage: dev
[vagrant@ansible ansible-files]$ ansible-inventory -i hosts.yml --graph
@all:
  |--@ungrouped:
  |  |--node1
  |--@web:
  |  |--node2
  |  |--node3
[vagrant@ansible ansible-files]$

group_vars ディレクトリ

group_vars ディレクトリを作成します

[vagrant@ansible ansible-files]$ mkdir group_vars/
[vagrant@ansible ansible-files]$

インベントリからグループに関する部分を抽出(網掛け部分)します。

---
all:
  vars:
    ansible_user: vagrant
  hosts:
    node1:
      ansible_host: 192.168.1.161
      ansible_ssh_private_key_file: ~/.ssh/node1_key
      stage: prod
  children:
    web:
      vars:
        stage: dev
      hosts:
        node2:
          ansible_host: 192.168.1.162
          ansible_ssh_private_key_file: ~/.ssh/node2_key
        node3:
          ansible_host: 192.168.1.163
          ansible_ssh_private_key_file: ~/.ssh/node3_key

最初は all グループ、 2 つめは web グループに関する部分なので、ファイル名は次のとおりです。

  • all.yml
  • web.yml

group_vars/all.ymlファイルの内容です。

---
ansible_user: vagrant

group_vars/web.ymlファイルの内容です。

---
stage: dev

インベントリファイルhosts.ymlからグループの部分を切り出したあとの状態です。

---
all:
  hosts:
    node1:
      ansible_host: 192.168.1.161
      ansible_ssh_private_key_file: ~/.ssh/node1_key
      stage: prod
  children:
    web:
      hosts:
        node2:
          ansible_host: 192.168.1.162
          ansible_ssh_private_key_file: ~/.ssh/node2_key
        node3:
          ansible_host: 192.168.1.163
          ansible_ssh_private_key_file: ~/.ssh/node3_key

host_vars ディレクトリ

host_vars ディレクトリを作成します

[vagrant@ansible ansible-files]$ mkdir host_vars/
[vagrant@ansible ansible-files]$

インベントリからグループに関する部分を抽出(網掛け部分)します。

---
all:
  vars:
    ansible_user: vagrant
  hosts:
    node1:
      ansible_host: 192.168.1.161
      ansible_ssh_private_key_file: ~/.ssh/node1_key
      stage: prod
  children:
    web:
      vars:
        stage: dev
      hosts:
        node2:
          ansible_host: 192.168.1.162
          ansible_ssh_private_key_file: ~/.ssh/node2_key
        node3:
          ansible_host: 192.168.1.163
          ansible_ssh_private_key_file: ~/.ssh/node3_key

ホスト名がファイル名になるので、各管理対象ホストのファイル名は次のとおりです。

  • node1.yml
  • node2.yml
  • node3.yml

host_vars/node1.ymlファイルの内容です。

---
ansible_host: 192.168.1.161
ansible_ssh_private_key_file: ~/.ssh/node1_key
stage: prod

host_vars/node2.ymlファイルの内容です。

---
ansible_host: 192.168.1.162
ansible_ssh_private_key_file: ~/.ssh/node2_key

host_vars/node3.ymlファイルの内容です。

---
ansible_host: 192.168.1.163
ansible_ssh_private_key_file: ~/.ssh/node3_key

インベントリファイルhosts.ymlから各管理対象ホストの部分を切り出したあとの状態です。

---
all:
  vars:
    ansible_user: vagrant
  hosts:
    node1:
  children:
    web:
      vars:
        stage: dev
      hosts:
        node2:
        node3:

インベントリの切り出し後の確認

インベントリからグループ固有の部分をgroup_vars ディレクトリに、管理対象ホスト固有の部分をhost_vars ディレクトリに切り出した後のhosts.ymlファイルの状態です。

---
all:
  hosts:
    node1:
  children:
    web:
      hosts:
        node2:
        node3:

グループ構成と管理対象ホストだけのスッキリした状態です。ディレクトリとファイルの配置状況です。

[vagrant@ansible ansible-files]$ tree
.
├── group_vars
│   ├── all.yml
│   └── web.yml
├── hosts.yml
└── host_vars
    ├── node1.yml
    ├── node2.yml
    └── node3.yml

2 directories, 6 files
[vagrant@ansible ansible-files]$

ansible-inventoryコマンドを実行し、各ファイルに切り出す前と同じか確認しました。同じ結果になっています。

[vagrant@ansible ansible-files]$ ansible-inventory -i hosts.yml --list --yaml
all:
  children:
    ungrouped:
      hosts:
        node1:
          ansible_host: 192.168.1.161
          ansible_ssh_private_key_file: ~/.ssh/node1_key
          ansible_user: vagrant
          stage: prod
    web:
      hosts:
        node2:
          ansible_host: 192.168.1.162
          ansible_ssh_private_key_file: ~/.ssh/node2_key
          ansible_user: vagrant
          stage: dev
        node3:
          ansible_host: 192.168.1.163
          ansible_ssh_private_key_file: ~/.ssh/node3_key
          ansible_user: vagrant
          stage: dev
[vagrant@ansible ansible-files]$ ansible-inventory -i hosts.yml --graph
@all:
  |--@ungrouped:
  |  |--node1
  |--@web:
  |  |--node2
  |  |--node3
[vagrant@ansible ansible-files]$

インベントリの演習

  1. インベントリに関するファイルを編集してください。
  • node1.ymlファイルから変数 stage の行を削除
  • all.ymlファイルの末尾に削除した行を追加
  1. ansible-inventoryコマンドを実行し、 all グループと web グループのどちらの変数の値が優先されるのか確認してください。

解答

編集後のhost_vars/node1.ymlファイルの内容です。

---
ansible_host: 192.168.1.161
ansible_ssh_private_key_file: ~/.ssh/node1_key

編集後のgroup_vars/all.ymlファイルの内容です。

---
ansible_user: vagrant
stage: prod

ansible-inventoryコマンドの実行結果です。

[vagrant@ansible ansible-files]$ ansible-inventory -i hosts.yml --list --yaml
all:
  children:
    ungrouped:
      hosts:
        node1:
          ansible_host: 192.168.1.161
          ansible_ssh_private_key_file: ~/.ssh/node1_key
          ansible_user: vagrant
          stage: prod
    web:
      hosts:
        node2:
          ansible_host: 192.168.1.162
          ansible_ssh_private_key_file: ~/.ssh/node2_key
          ansible_user: vagrant
          stage: dev
        node3:
          ansible_host: 192.168.1.163
          ansible_ssh_private_key_file: ~/.ssh/node3_key
          ansible_user: vagrant
          stage: dev
[vagrant@ansible ansible-files]$

group_vars/all.ymlファイルの内容がすべてのグループ内の管理対象ホストに適用されてからgroup_vars/web.ymlファイルの内容が適用されました。この結果から同じ変数が複数のグループで定義されている場合、all グループよりも個別のグループ(今回は web グループ)の定義が優先されます。