話題の記事

Ansible inventoryパターン

2015.11.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Ansibleではinventoryに対象ホストを定義します。 適用したいインフラ構成が複数ある場合、playbook毎にグループ化してください。 グループ化した場合、変数はそれぞれのgroup varsに定義できます。 詳しくは、前回のエントリーを参照してください。

inventoryの構成方法には幾つかのパターンがあります。 対象とするシステムの規模や特徴にあわせて選択しましょう。

なお、パターンを整理するにあたって、Ansibleのインベントリファイルでステージを切り替えるを参考にしました。

ベーシックパターン

開発環境・検証環境・本番環境といった目的毎に環境を作る必要がなく、ひとつの環境(本番環境)のみの場合は、inventoryファイルもひとつで十分です。 hostsという名前のファイルを作成し、inventoryを定義しましょう。

構成は次のようになります。

.
├── group_vars
│   ├── all.yml
│   ├── batch.yml
│   └── web.yml
├── hosts
├── roles
├── site.yml
├── batch.yml
└── web.yml

hostsには、次のようにグループ毎にホストを列挙します。

[web]
10.0.11.121
10.0.11.122
[batch]
10.0.21.100

対応するplaybookは、web.yml, batch.ymlです。 次のように、hostsでグループを指定してください。

#
# web.yml
#
- hosts: web
  sudo: yes
  remote_user: {{ ssh_remote_user }}
  roles:
    - apache2

playbookで利用するグループ毎の変数は、group_vars/web.yml, group_vars/batch.yml に定義します。

#
# web.yml
# 
web_domain: “www.example.com”

全グループで共通の変数は、group_vars/all.yml に定義します。

#
# all.yml
# 
ssh_remote_user: ec2-user

全インフラを一括して実行するplaybookは、site.ymlです。 次のようにincludeを利用し、各playbookを読み込みます。

#
# site.yml
#
- include: batch.yml
- include: web.yml

playbookの実行は次のようになります。

$ ansible-playbook -i hosts web.yml
$ ansible-playbook -i hosts batch.yml
$ ansible-playbook -i hosts site.yml

ステージパターン

開発環境・検証環境・本番環境といった目的毎に環境が必要な場合に適用するパターンです。 ただし、各環境毎の違いがホスト名・実行するrole・幾つかのグループ変数といったケースに適用し、各環境でグループ変数が大きく異なる場合は、後述の詳細ステージパターンを適用します。 このパターンは、Ansible Best Practiceで紹介されている構成です。

構成は次のようになります。

.
├── group_vars
│   ├── all.yml
│   ├── batch.yml
│   └── web.yml
├── vars
│   ├── stg.yml
│   └── prd.yml
├── stg
├── prd
├── roles
├── site.yml
├── batch.yml
└── web.yml

ベーシックパターンとの違いは、inventoryが環境毎にstg, prdと定義していることと、各環境に対応した変数ファイル vars/stg.yml, vars/prd.yml です。

はじめにinventoryファイルです。 inventoryには :vars を使うことで、変数を定義できるため、環境名を定義する変数stageを定義しておきます。

# stg
[web]
10.0.11.121
10.0.11.122
[batch]
10.0.21.100
[all:vars]
stage=stg
# prd
[web]
10.1.11.121
10.1.11.122
[batch]
10.1.21.100
[all:vars]
stage=prd

グループ毎に対応するplaybook(web.yml, batch.yml)を作ることは変わりません。 ただし、環境毎の変数ファイルを適用するため、vars_filesを設定します。

#
# web.yml
#
- hosts: web
  sudo: yes
  remote_user: {{ ssh_remote_user }}
  vars_files:
    - vars/{{ stage }}.yml
  roles:
    - apache2
    - { role:cloud watch, when: "stage == 'prd'" }

変数stageを利用していますが、これはinventoryで設定されるため、それぞれの環境で、vars/stg.yml, vars/prd.ymlが読み込まれることになります。 また、roleはstageを変数として条件付けし、本番環境のみに適用する設定も容易です。

グループ変数を定義する group_vars/web.yml, group_vars/batch.yml, group_vars/all.yml については同様です。 ただし、web.yml, batch.ymlは、prdとstgのどの環境でも適用されるので注意してください。

つまり、環境毎に違いがない変数は、group_vars以下のファイルに、環境毎に値が異なる変数はvarsの下に定義します

inventoryファイルはansible-playbookコマンドの実行時、-iオプションで指定するため、次のように本番環境と検証環境で使い分けることになります。

$ ansible-playbook -i stg web.yml
$ ansible-playbook -i prd web.yml

詳細ステージパターン

ステージパターンと同様に、開発環境・検証環境・本番環境といった目的毎に環境が必要な場合に適用するパターンです。 設定ファイルなどで多くの変数を参照し、それらが環境毎に異なる部分が多い場合、詳細ステージパターンが有効です。

構成は次のようになります。

.
├── hosts
│   ├── prd
│   │   ├── group_vars
│   │   │   ├── all.yml
│   │   │   ├── common.yml
│   │   │   └── webserver.yml
│   │   └── inventory
│   └── stg
│       ├── group_vars
│       │   ├── all.yml
│       │   ├── common.yml
│       │   └── webserver.yml
│       └── inventory
├── roles
├── site.yml
├── batch.yml
└── web.yml

詳細ステージパターンでは、hosts/prd, hosts/stg ディレクトリがinventoryとなります。 Ansibleではファイルだけではなくディレクトリもinventoryとして指定でき、この時はinventoryディレクトリ配下のgroup_varsを読み込むような仕組みになっています。

ホストは、hosts/prd/inventory, hosts/stg/inventory に定義します。 all:varsは不要なので、ホスト名の列挙のみです。

# hosts/stg/inventory
[web]
10.0.11.121
10.0.11.122
[batch]
10.0.21.100
# hosts/prd/inventory
[web]
10.1.11.121
10.1.11.122
[batch]
10.1.21.100

代わりに、hosts/stg/all.yml, hosts/prd/all.ymlに環境毎に全ホストに有効な変数を定義します。

#
# hosts/stg/all.yml
# 
stage: stg
ssh_remote_user: ec2-user
#
# hosts/prd/all.yml
# 
stage: prd
ssh_remote_user: ec2-user

グループ変数を定義する hosts/stg/group_vars/web.yml, hosts/stg/group_vars/batch.yml, hosts/prd/group_vars/web.yml, hosts/prd/group_vars/batch.yml は、環境毎に設定します。 すなわち、環境毎に全ての変数をわけて定義できることになります。 このため、confファイルの細かい設定を環境毎に書き分けることが容易です(詳細パターンでない場合、すべての変数がvars以下に定義され読みにくくなります)。

<VirtualHost *:443>
        ServerName https://{{ web_domain }}:443
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/{{ apache_log_suffix }}_error.log
        CustomLog ${APACHE_LOG_DIR}/{{ apache_log_suffix }}_access.log combined
</VirtualHost>

ansible-playbookコマンドの実行時オプションは次のように指定します。

$ ansible-playbook -i hosts/stg web.yml
$ ansible-playbook -i hosts/prd web.yml

まとめ

検証環境と本番環境などの複数の環境がない場合は、ベーシックパターンで構成します。 検証環境と本番環境などの複数の環境がある場合は、ステージパターンまたはステージパターン(詳細)で構成します。 この時、環境毎の設定がホスト名・実行するrole・一部の変数といった範囲である場合はステージパターンを、設定ファイルの細部まで変数が異なってくる場合はステージパターン(詳細)で構成してください。