条件分岐

タスクにwhenディレクティブを使用して条件を設定することで、条件を満たしたときだけタスクを実行するようにできます。


使用できる演算子

条件を作成するときに使用できる演算子にはいくつかの種類があります。

比較演算子
演算子 説明( true のとき)
X == Y X の値と Y の値が等しいとき
X != Y X の値と Y の値が等しくないとき
X > Y X の値が Y の値より大きいとき
X >= Y X の値が Y の値より大きいか等しいとき
X < Y X の値が Y の値より小さいとき
X <= Y X の値と Y の値より小さいか等しいとき
論理演算子(優先順位が高い順)
演算子 説明( true のとき)
not 条件X 条件X が False のとき
条件X and 条件Y 条件X と条件Y がともに True のとき
条件X or 条件Y 条件X か条件Y のどちらかが True のとき
in 演算子
演算子 説明( true のとき)
A in [X, Y, Z] A と同じ値が X, Y, Z の中にあるとき
A not in [X, Y, Z] A と同じ値が X, Y, Z の中にないとき

ご用心

  • 論理演算子を使用して複数の条件を結合するとき、論理演算子の優先(評価)順序を踏まえて結合します。
  • ()を使用して明示的に条件の評価順序を指定できます。

when ディレクティブ

whenディレクティブを使用してタスクに条件(条件式、条件文)を設定します。

注釈

条件式に変数を含む場合、その変数は{{}}でくくりません。

比較演算子

比較演算子は 2 つの値を比較するときに使用します。例えば、CentOS の管理対象ホストだけをシャットダウンしたいのであればファクト変数ansible_distributionの値が CentOS で判断できます。

- name: 特定の OS の管理対象ホストをシャットダウンする
  hosts: all

  tasks:
  - name: CentOS だけシャットダウンする
    command: /sbin/shutdown -t 15
    become: yes
    when: ansible_facts['distribution'] == "CentOS"

実行前の管理対象ホストの状態です。

C:\vagrant\ansible-study2>vagrant status
Current machine states:

centos7                   running (virtualbox)
centos8                   running (virtualbox)
debian10                  running (virtualbox)
ubuntu18                  running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

C:\vagrant\ansible-study2>

実行ログです。whenディレクティブに指定した条件に合致する管理対象ホストは changed です。合致しない管理対象ホストはタスクの実行をスキップしたので skipping です。

[vagrant@ansible ansible-files]$ ansible-playbook -i hosts2.yml shutdown.yml

PLAY [特定の OS の管理対象ホストをシャットダウンする] ****************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [debian10]
ok: [centos7]
ok: [ubuntu18]
ok: [centos8]

TASK [CentOS だけシャットダウンする] ***********************************************************************************************************************************
skipping: [debian10]
skipping: [ubuntu18]
[WARNING]: Module invocation had junk after the JSON data:   Broadcast message from root@centos7 (Sun 2020-05-03 14:05:07 UTC):    The system is going down for power-off at Sun 2020-05-03 14:06:07 UTC!
changed: [centos7]
changed: [centos8]

PLAY RECAP **************************************************************************************************************************************************
centos7                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
centos8                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
debian10                   : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
ubuntu18                   : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

[vagrant@ansible ansible-files]$

実行後の管理対象ホストの状態です。実行ログで changed になった管理対象ホストが poweroff です。

C:\vagrant\ansible-study2>vagrant status
Current machine states:

centos7                   poweroff (virtualbox)
centos8                   poweroff (virtualbox)
debian10                  running (virtualbox)
ubuntu18                  running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

C:\vagrant\ansible-study2>

論理演算子

論理演算子は 2 つ以上の条件を結合した少し複雑な条件を作成するときに使用します。論理演算子を用いた条件は優先順位にもとづいて評価順序が決定します。()を用いて条件をグループ化した場合、グループの評価が優先されます。

or 演算子

CentOS か Debian の管理対象ホストをシャットダウンするプレイです。

- name: 特定の OS の管理対象ホストをシャットダウンする
  hosts: all

  tasks:
  - name: CentOS か Debian だけシャットダウンする
    command: /sbin/shutdown -t 15
    become: yes
    when: ansible_facts['distribution'] == "CentOS" or ansible_facts['distribution'] == "Debian"

whenディレクティブに指定した条件は次のように書き直せます。

- name: 特定の OS の管理対象ホストをシャットダウンする
  hosts: all

  tasks:
  - name: CentOS か Debian だけシャットダウンする
    command: /sbin/shutdown -t 15
    become: yes
    when: ansible_facts['distribution'] == "CentOS"
       or ansible_facts['distribution'] == "Debian"

実行前の管理対象ホストの状態です。

C:\vagrant\ansible-study2>vagrant status
Current machine states:

centos7                   running (virtualbox)
centos8                   running (virtualbox)
debian10                  running (virtualbox)
ubuntu18                  running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

C:\vagrant\ansible-study2>

実行ログです。 CentOS と Debian の管理対象ホストがwhenディレクティブに指定した条件に合致したので changed です。Ubuntu の管理対象ホストは条件に合致せずタスクの実行をスキップしたので skipping です。

[vagrant@ansible ansible-files]$ ansible-playbook -i hosts2.yml shutdown.yml

PLAY [特定の OS の管理対象ホストをシャットダウンする] ****************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [debian10]
ok: [centos7]
ok: [ubuntu18]
ok: [centos8]

TASK [CentOS か Debian だけシャットダウンする] **************************************************************************************************************************
skipping: [ubuntu18]
changed: [debian10]
[WARNING]: Module invocation had junk after the JSON data:   Broadcast message from root@centos7 (Mon 2020-05-04 01:00:44 UTC):    The system is going down for power-off at Mon 2020-05-04 01:01:44 UTC!
changed: [centos7]
changed: [centos8]

PLAY RECAP **************************************************************************************************************************************************
centos7                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
centos8                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
debian10                   : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ubuntu18                   : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

[vagrant@ansible ansible-files]$

実行後の管理対象ホストの状態です。実行ログと同じ結果です。

C:\vagrant\ansible-study2>vagrant status
Current machine states:

centos7                   poweroff (virtualbox)
centos8                   poweroff (virtualbox)
debian10                  poweroff (virtualbox)
ubuntu18                  running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

C:\vagrant\ansible-study2>

and 演算子

CentOS8 の管理対象ホストをシャットダウンするプレイです。

- name: 特定の OS の管理対象ホストをシャットダウンする
  hosts: all

  tasks:
  - name: CentOS8 だけシャットダウンする
    command: /sbin/shutdown -t 15
    become: yes
    when: ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "8"

whenディレクティブに指定した論理演算子がすべて and の場合、条件をリスト形式で書き直せます。

- name: 特定の OS の管理対象ホストをシャットダウンする
  hosts: all

  tasks:
  - name: CentOS8 だけシャットダウンする
    command: /sbin/shutdown -t 15
    become: yes
    when:
      - ansible_facts['distribution'] == "CentOS"
      - ansible_facts['distribution_major_version'] == "8"

実行前の管理対象ホストの状態です。

C:\vagrant\ansible-study2>vagrant status
Current machine states:

centos7                   running (virtualbox)
centos8                   running (virtualbox)
debian10                  running (virtualbox)
ubuntu18                  running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

C:\vagrant\ansible-study2>

実行ログです。 CentOS8 の管理対象ホストがwhenディレクティブに指定した条件に合致したので changed です。 CentOS8 以外の管理対象ホストは条件に合致せずタスクの実行をスキップしたので skipping です。

[vagrant@ansible ansible-files]$ ansible-playbook -i hosts2.yml shutdown.yml

PLAY [特定の OS の管理対象ホストをシャットダウンする] ****************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [debian10]
ok: [centos7]
ok: [ubuntu18]
ok: [centos8]

TASK [CentOS8 だけシャットダウンする] **********************************************************************************************************************************
skipping: [centos7]
skipping: [debian10]
skipping: [ubuntu18]
changed: [centos8]

PLAY RECAP **************************************************************************************************************************************************
centos7                    : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
centos8                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
debian10                   : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
ubuntu18                   : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

[vagrant@ansible ansible-files]$

実行後の管理対象ホストの状態です。実行ログと同じ結果です。

C:\vagrant\ansible-study2>vagrant status
Current machine states:

centos7                   running (virtualbox)
centos8                   poweroff (virtualbox)
debian10                  running (virtualbox)
ubuntu18                  running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

C:\vagrant\ansible-study2>

論理演算子の応用

少し複雑な例として or と and を併用した例を示します。CentOS8 か Ubuntu の管理対象ホストをシャットダウンするプレイです。

- name: 特定の OS の管理対象ホストをシャットダウンする
  hosts: all

  tasks:
  - name: CentOS8 か Ubuntu をシャットダウンする
    command: /sbin/shutdown -t 15
    become: yes
    when: ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "8" or ansible_facts['distribution'] == "Ubuntu"

whenディレクティブ内の変数 ansible_facts['distribution_major_version'] が CentOS 用なのか Ubuntu 用なのかがわかりにく状態です。これをディストリビューションごとに()でくくって書き直した結果です。どの条件がどのディストリビューションのものか明確になり、誤読する可能性が低下しました。

- name: 特定の OS の管理対象ホストをシャットダウンする
  hosts: all

  tasks:
  - name: CentOS8 か Ubuntu をシャットダウンする
    command: /sbin/shutdown -t 15
    become: yes
    when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "8")
       or (ansible_facts['distribution'] == "Ubuntu")

実行前の管理対象ホストの状態です。

C:\vagrant\ansible-study2>vagrant status
Current machine states:

centos7                   running (virtualbox)
centos8                   running (virtualbox)
debian10                  running (virtualbox)
ubuntu18                  running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

C:\vagrant\ansible-study2>

実行ログです。 CentOS8 と Ubuntu の管理対象ホストがwhenディレクティブに指定した条件に合致したので changed です。それ以外の管理対象ホストは条件に合致せずタスクの実行をスキップしたので skipping です。

[vagrant@ansible ansible-files]$ ansible-playbook -i hosts2.yml shutdown.yml

PLAY [特定の OS の管理対象ホストをシャットダウンする] ****************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************
ok: [debian10]
ok: [centos7]
ok: [ubuntu18]
ok: [centos8]

TASK [CentOS8 か Ubuntu をシャットダウンする] **************************************************************************************************************************
skipping: [centos7]
skipping: [debian10]
changed: [ubuntu18]
changed: [centos8]

PLAY RECAP **************************************************************************************************************************************************
centos7                    : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
centos8                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
debian10                   : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
ubuntu18                   : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[vagrant@ansible ansible-files]$

実行後の管理対象ホストの状態です。実行ログと同じ結果です。

C:\vagrant\ansible-study2>vagrant status
Current machine states:

centos7                   running (virtualbox)
centos8                   poweroff (virtualbox)
debian10                  running (virtualbox)
ubuntu18                  poweroff (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

C:\vagrant\ansible-study2>

in 演算子

or 演算子で使用した CentOS か Debian の管理対象ホストをシャットダウンするプレイを in 演算子で書き直した結果です。

- name: 特定の OS の管理対象ホストをシャットダウンする
  hosts: all

  tasks:
  - name: CentOS か Debian をシャットダウンする
    command: /sbin/shutdown -t 15
    become: yes
    when: ansible_facts['distribution'] in ["CentOS", "Debian"]

in 演算子は in の左側に書いた値が[]の中に書いた値と同じものがあるかを判断します( not in の場合はないかを判断します)。今回のような使い方の場合、 or 演算子を使用するより in 演算子を使用した方が条件の意味がわかりやすくなります。