CUBE SUGAR CONTAINER

技術系のこと書きます。

Ansible: 特定のタスクをグループの全ホスト上で実行する際のイディオム

今回は Ansible を使う際、特定のタスクをグループの全ホスト上で実行する場合のイディオムについて書いてみる。 尚、これは Playbook の hosts にグループを書いて実行するというわけではなく、Playbook の中の特定のタスクを任意のグループの全ホスト上で実行することを指している。

Ansible をインストールする

今回は Mac OSX を使ったので Homebrew でインストールしておく。 インストール方法について特に問わない。

$ brew install ansible

Inventory を用意する

動作確認のために仮想マシンなどを作るのは面倒なので全てローカルホストで済ませてみる。 以下にようにすることで localhosts グループの中に localhost[012] ができる。 これで Ansible 的にはそれぞれが別のホストとして扱われる。

$ cat << EOF > hosts
[localhosts]
localhost1 ansible_connection=local
localhost2 ansible_connection=local
localhost3 ansible_connection=local
EOF

Playbook を用意する

さて、肝心のイディオムは Playbook にある。 Playbook の中では groups.* という変数経由で、そのグループに所属しているホストにアクセスできるため、それを with_items に指定する。 すると {{ item }} という形でグループのホスト名を列挙できるため、それを delegate_to に指定すれば良い。 これでグループに所属している全ホスト上でタスクが実行されることになる。 尚、Playbook 自体の実行ホストにも localhost を指定している。

$ cat << EOF > site.yml
---
- hosts:
    - localhost
  tasks:
    - name: Greet
      shell: echo "Hello, World!"
      delegate_to: "{{ item }}"
      with_items: groups.localhosts

EOF

動作を確認する

前述した Inventory と Playbook を実行してみよう。 Greet タスクが 3 回実行されれば上手く動作していることになる。

$ ansible-playbook -i hosts site.yml -v

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

GATHERING FACTS *************************************************************** 
ok: [localhost]

TASK: [Greet] ***************************************************************** 
changed: [localhost -> localhost1] => (item=localhost1) => {"changed": true, "cmd": "echo \"Hello, World!\"", "delta": "0:00:00.004664", "end": "2015-09-27 02:46:29.672936", "item": "localhost1", "rc": 0, "start": "2015-09-27 02:46:29.668272", "stderr": "", "stdout": "Hello, World!", "warnings": []}
changed: [localhost -> localhost2] => (item=localhost2) => {"changed": true, "cmd": "echo \"Hello, World!\"", "delta": "0:00:00.005046", "end": "2015-09-27 02:46:29.777870", "item": "localhost2", "rc": 0, "start": "2015-09-27 02:46:29.772824", "stderr": "", "stdout": "Hello, World!", "warnings": []}
changed: [localhost -> localhost3] => (item=localhost3) => {"changed": true, "cmd": "echo \"Hello, World!\"", "delta": "0:00:00.005605", "end": "2015-09-27 02:46:29.890963", "item": "localhost3", "rc": 0, "start": "2015-09-27 02:46:29.885358", "stderr": "", "stdout": "Hello, World!", "warnings": []}

PLAY RECAP ******************************************************************** 
localhost                  : ok=2    changed=1    unreachable=0    failed=0   

ばっちり。