■ はじめに
Ansible では、管理対象のホストをグループ化してインベントリファイルに定義できます。Playbook 内にグループを指定すると、指定したグループに所属するホストのみが対象になります。
では「グループAとBに両方に所属しているホスト」を対象にしたい場合はどのようにしたらよいでしょうか。
例えば以下のようなインベントリファイルがある場合、host02
、host03
を対象にしたい、というケースです。
[group_a] host01 host02 host03 [group_b] host02 host03 host04
この記事では、両方に所属しているホストを対象にする2つの方法を、簡単な例とともにご紹介します。
- 動作確認環境: Ansible 2.3.0, 2.7.9
■ 方法1: play の hosts ディレクティブにグループを and 条件で指定する
Pkabbook内(のplay)の hosts
ディレクティブには、複数の対象を and 条件で指定できます。この機能を利用する方法です。
参考: https://docs.ansible.com/ansible/latest/user_guide/intro_patterns.html
- playbook
- hosts: group_a:&group_b gather_facts: no tasks: - name: debug test debug: msg: "I am {{ inventory_hostname }}."
上記のように group_a:&group_b
と指定することで、group_a
に所属、かつ group_b
にも所属、という指定になります。
- 実行例
$ ansible-playbook -i inventory test.yml PLAY [group_a:&group_b] **************************************************************** TASK [debug test] ********************************************************************** ok: [host02] => { "msg": "I am host02." } ok: [host03] => { "msg": "I am host03." } PLAY RECAP ****************************************************************************** host02 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 host03 : ok=1 changed=0 unreachable=0 failed=0 skipped=0
両グループに所属している、host02
、host03
が対象となりました。
なお、--list-hosts
オプションを付けると実処理をせずに対象ホストを確認できます。
$ ansible-playbook -i inventory test.yml --list-hosts playbook: test.yml play #1 (group_a:&group_b): group_a:&group_b TAGS: [] pattern: [u'group_a:&group_b'] hosts (2): host02 host03
■ 方法2: -l オプションと組み合わせる
ansible-playbook
コマンドには、対象ホストを絞り込む -l
または --limit
オプションがあります。この機能と、hosts
ディレクティブを併用する方法です。
参考: https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html#cmdoption-ansible-playbook-l
- playbook
- hosts: group_a gather_facts: no tasks: - name: debug test debug: msg: "I am {{ inventory_hostname }}."
Playbook としては group_a
を対象としています。
- 実行例
$ ansible-playbook -i inventory test.yml -l group_b PLAY [group_a] *************************************************************************** TASK [debug test] ************************************************************************ ok: [host02] => { "msg": "I am host02." } ok: [host03] => { "msg": "I am host03." } PLAY RECAP ******************************************************************************* host02 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 host03 : ok=1 changed=0 unreachable=0 failed=0 skipped=0
-l group_b
で絞ることによって、結果的に両グループに所属している host02
、host03
が対象となりました。
--list-hosts
オプションでも確認してみます。
$ ansible-playbook -i inventory test.yml -l group_b --list-hosts playbook: test.yml play #1 (group_a): group_a TAGS: [] pattern: [u'group_a'] hosts (2): host02 host03
■ 方法3: when で group_names で判断する [2019/10/16 追記]
Play 単位ではなく、when が効く ロールや block 、タスクなどで使える方法です。
- hosts: all roles: - role: test when: "'group_a' in group_names and 'group_b' in group_names" tasks: - debug: msg: In group_a and group_b when: "'group_a' in group_names and 'group_b' in group_names"
@satoh_fumiyasu さんにアイディアいただきました。ありがとうございます。
when: で group_names を見る方法とか。 #ansiblejp
— ふみやす@シェルまおう(自称でない) FGO:838,149,789 (@satoh_fumiyasu) October 16, 2019
- hosts: all
roles:
- role: test
when: "'group_a' in group_names and 'group_b' in group_names"
tasks:
- debug:
msg: In group_a and group_b
when: "'group_a' in group_names and 'group_b' in group_names"
■ まとめ
複数のグループに所属しているホストを対象にする方法を2つご紹介しました。 ただ、インベントリとして新たにグループを定義したほうが、メンテナンス性が良いケースもあるかもしれません。必要に応じて使い分けるのが良いと思います。