読者です 読者をやめる 読者になる 読者になる

破棄されたブログ

このブログは破棄されました。

Ansible の Inventory file についておさらい

Ansible インフラ

この記事は、 2015 tech-yuruyuru アドベントカレンダー 3 日目の記事です。

Inventory file とは何か

Ansible は、インフラ内の複数システムに対して同時に動作します。 Inventory file は、 Ansible が動作する対象のシステムを列挙するためのファイルです。

Host と Group

では、実際に Inventory file を見ていきます

まず、動作対象となる以下のシステムを Vagarant で立ち上げます

  • mail: メールサーバ
  • web1, web2: Web サーバ
  • db1, db2: DB サーバ
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "debian-8.2"
  config.vm.network "private_network", type: "dhcp"
  # 動作の確認が目的なので SSH 秘密鍵を INSECURE なままにしておく
  config.ssh.insert_key = false

  [:mail, :web1, :web2, :db1, :db2].each do |name|
    config.vm.define name do |server|
      server.vm.hostname = name
      # mDNS を使うため Avahi をインストールする
      server.vm.provision "shell", inline: <<-SHELL
        sudo apt-get update && sudo apt-get upgrade -y
        sudo apt-get install -y avahi-daemon
      SHELL
    end
  end
end
$ vagrant up
Bringing machine 'mail' up with 'virtualbox' provider...
Bringing machine 'web1' up with 'virtualbox' provider...
Bringing machine 'web2' up with 'virtualbox' provider...
Bringing machine 'db1' up with 'virtualbox' provider...
Bringing machine 'db2' up with 'virtualbox' provider...
... 後略
$

次に inventory というファイル名で、 Inventory file を作成します

# ./inventory
mail.local

[webservers]
web1.local
web2.local

[dbservers]
db1.local
db2.local

mail.local, web1.local といったように、 動作対象となる Host を列挙します

[webservers] のようにブラケット ([]) で囲まれた名前は、 Group の名前です。 Group は、目的や操作のタイミングなどで Host をグルーピングするために使います

一度、 Ansible でこの Inventory file を使って ping を打ってみます

$ # すべての Host に ping
$ # ansible [host] -u [user] --private-key=[/path/to/private_key] -m ping -i [/path/to/inventory_file]
$ ansible '*'  -u 'vagrant' --private-key='~/.vagrant.d/insecure_private_key' -m ping -i ./inventory
web1.local | success >> {
    "changed": false, 
    "ping": "pong"
}

mail.local | success >> {
    "changed": false, 
    "ping": "pong"
}

db2.local | success >> {
    "changed": false, 
    "ping": "pong"
}

web2.local | success >> {
    "changed": false, 
    "ping": "pong"
}

db1.local | success >> {
    "changed": false, 
    "ping": "pong"
}

$ # Host を指定して ping
$ ansible web1.local  -u 'vagrant' --private-key='~/.vagrant.d/insecure_private_key' -m ping -i ./inventory 
web1.local | success >> {
    "changed": false, 
    "ping": "pong"
}

$ # Group を指定して ping
$ ansible dbservers  -u 'vagrant' --private-key='~/.vagrant.d/insecure_private_key' -m ping -i ./inventory 
db1.local | success >> {
    "changed": false, 
    "ping": "pong"
}

db2.local | success >> {
    "changed": false, 
    "ping": "pong"
}

無事、 ping が打てました

Host Variable

注意:

Host Variable/Group Variable を Inventory ファイル書くことは、 推奨されていません Splitting Out Host and Group Specific Data

Host の変数を Inventory file 内で定義することもできます

http_porthoge という Host Variable を web1, web2 に定義してみます

# ./inventory
[webservers]
web1.local http_port=80 hoge=fuga
web2.local http_port=80 hoge=piyo

Host Varible が定義されたこと Playbook を作成して確認してみます

# inventory-host_variable.yml
- hosts: webservers
  tasks:
  - debug: msg="http_port {{ http_port }}"
  - debug: msg="hoge {{ hoge }}"
$ # ansible-playbook -u[user] --private-key=[/path/to/private_key] -i [/path/to/inventory_file] [/path/to/playbook]
$ ansible-playbook -uvagrant --private-key=~/.vagrant.d/insecure_private_key -i inventory playbook-host_variable.yml

PLAY [webservers] ************************************************************* 

GATHERING FACTS *************************************************************** 
ok: [web1.local]
ok: [web2.local]

TASK: [debug msg="http_port {{ http_port }}"] ********************************* 
ok: [web1.local] => {
    "msg": "http_port 80"
}
ok: [web2.local] => {
    "msg": "http_port 80"
}

TASK: [debug msg="hoge {{ hoge }}"] ******************************************* 
ok: [web1.local] => {
    "msg": "hoge fuga"
}
ok: [web2.local] => {
    "msg": "hoge piyo"
}

PLAY RECAP ******************************************************************** 
web1.local                 : ok=3    changed=0    unreachable=0    failed=0   
web2.local                 : ok=3    changed=0    unreachable=0    failed=0

Host ごとに Host variable が定義されていることが確認できました

Group Variable

Host Variable と同様に、 Group の変数を Inventory file 内で定義することもできます

Group Variable は、 [group_name:vars] で定義します

# ./inventory
[webservers]
web1.local
web2.local

[webservers:vars]
http_port=80
time_zone=Tokyo/Asia

Group Varible が定義されたこと Playbook を作成して確認してみます

# inventory-host_variable.yml
- hosts: webservers
  tasks:
  - debug: msg="http_port {{ http_port }}"
  - debug: msg="time_zone {{ time_zone }}"
$ ansible-playbook -uvagrant --private-key=~/.vagrant.d/insecure_private_key -i inventory playbook-host_variable.yml 

PLAY [webservers] ************************************************************* 

GATHERING FACTS *************************************************************** 
ok: [web1.local]
ok: [web2.local]

TASK: [debug msg="http_port {{ http_port }}"] ********************************* 
ok: [web2.local] => {
    "msg": "http_port 80"
}
ok: [web1.local] => {
    "msg": "http_port 80"
}

TASK: [debug msg="time_zone {{ time_zone }}"] ********************************* 
ok: [web1.local] => {
    "msg": "time_zone Tokyo/Asia"
}
ok: [web2.local] => {
    "msg": "time_zone Tokyo/Asia"
}

PLAY RECAP ******************************************************************** 
web1.local                 : ok=3    changed=0    unreachable=0    failed=0   
web2.local                 : ok=3    changed=0    unreachable=0    failed=0 

Group 内の全ての Host に Group Variable が定義されたことがわかります

小グループ

Group の Group を作成することもできます

例として、 AWS で 2 つ Availability Zone に、 2 つずつ Web サーバをおいた場合を考えてみます

# ./inventory
# az-a に 2 台
[ap-norheast1a]
web[1:2].local

# az-c に 2 台
[ap-norheast1c]
web[3:4].local

[webservers:children]
ap-norheast1a
ap-norheast1c

# 親グループの Group Variable
[webservers:vars]
http_port=80

# 子グループの Group Variable
[ap-norheast1a:vars]
availability_zone=a

# 子グループの Group Variable
[ap-norheast1c:vars]
availability_zone=c
$ ansible-playbook -uvagrant --private-key=~/.vagrant.d/insecure_private_key -i inventory-group_of_group playbook-group_of_group.yml

PLAY [webservers] ************************************************************* 

GATHERING FACTS *************************************************************** 
ok: [web3.local]
ok: [web4.local]
ok: [web2.local]
ok: [web1.local]

TASK: [debug msg="http_port {{ http_port }}"] ********************************* 
ok: [web1.local] => {
    "msg": "http_port 80"
}
ok: [web3.local] => {
    "msg": "http_port 80"
}
ok: [web2.local] => {
    "msg": "http_port 80"
}
ok: [web4.local] => {
    "msg": "http_port 80"
}

TASK: [debug msg="availability_zone {{ availability_zone }}"] ***************** 
ok: [web1.local] => {
    "msg": "availability_zone a"
}
ok: [web2.local] => {
    "msg": "availability_zone a"
}
ok: [web3.local] => {
    "msg": "availability_zone c"
}
ok: [web4.local] => {
    "msg": "availability_zone c"
}

PLAY RECAP ******************************************************************** 
web1.local                 : ok=3    changed=0    unreachable=0    failed=0   
web2.local                 : ok=3    changed=0    unreachable=0    failed=0   
web3.local                 : ok=3    changed=0    unreachable=0    failed=0   
web4.local                 : ok=3    changed=0    unreachable=0    failed=0   

$ 

このように、

  • グループ内すべてで共通の Group Variable host_port が、 子グループ内の Host すべてで定義されていること
  • 子グループ内の Group Varialbe availability_zone が、 子グループごとに定義されている

ことがわかります

また、親グループと子グループで同じ名前の Group Variable が定義された場合、 子グループ側の Group Variable で上書きされるようです

[all:vars]

[all:vars] を用いると、すべてのホストに対して Group Variable を定義することができます

したがって、 SSH のユーザや秘密鍵のパスなどをまとめて定義できます

# ./inventory
# ...
[all:vars]
ansible_ssh_user=vagrant
ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key

これで、今まで以下のように、コマンドラインオプションで指定していた接続設定が

$ ansible-playbook -uvagrant --private-key=~/.vagrant.d/insecure_private_key -i inventory playbook.yml

以下のように省略できるようになります

$ ansible-playbook -i inventory playbook

便利な使い方

ポートの指定

host:port という形式でのポート指定

web1.local:22

ansible_port 変数を使ったポート指定

web1.local ansible_port=22

複数 Host のリスティング

[1:3][a:c] といった形式でまとめて Host を定義できます

web[1:2].local

ansible_ プレフィックスの Host Variable

ansible_port のように、 Ansible の挙動を制御するためのパラメータ (Host Variable) が いくつか存在しており、 List of Behavioral Inventory Parameters にリファレンスが掲載されています

参考資料

広告を非表示にする