概要
Ansible でblock とwhen を組み合わせて使っていた際に個人的に直感に反した挙動をしたので共有
動作確認バージョン
ansible-core 2.13.1
当初想定していた動作
以下のようなPlaybook があったとします
---
- name: Test block when condition
hosts: localhost
gather_facts: false
tasks:
- name: Block statement
when: block_condition is not defined
block:
- name: Set fact block_condition
ansible.builtin.set_fact:
block_condition: hoge
- name: Debug block_condition
ansible.builtin.debug:
var: block_condition
リファレンスを読んでいなかった私はブロック入る際の条件をwhen
で指定できると思っていました
なので、Block statement
タスク開始時点でblock_condition
が定義されていなければ、
block
内の全てのタスクが実行されるだろうと思っていた訳です
実際の動作
ところが、実際はblock
に付けたディレクティブ(when
) は内包される各task
に展開されるようです
こんなイメージ
---
- name: Test block when condition
hosts: localhost
gather_facts: false
tasks:
- name: Set fact block_condition
ansible.builtin.set_fact:
block_condition: hoge
when: block_condition is not defined
- name: Debug block_condition
ansible.builtin.debug:
var: block_condition
when: block_condition is not defined
実際に1つ目のPlaybook を動かすと2番目のタスクはスキップされることが分かります
PLAY [Test block when condition] ************************************************************************************************************************************************************************************************
TASK [Set fact block_condition] *************************************************************************************************************************************************************************************************
ok: [localhost]
TASK [Debug block_condition] ****************************************************************************************************************************************************************************************************
skipping: [localhost]
PLAY RECAP **********************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
よく見るとリファレンスに書いてありました😇
For example, a when statement is applied to the tasks within a block, not to the block itself.
loop
を除いた全てのディレクティブで同じことが言えるそうですね
All tasks in a block inherit directives applied at the block level. Most of what you can apply to a single task (with the exception of loops) can be applied at the block level, so blocks make it much easier to set data or directives common to the tasks. The directive does not affect the block itself, it is only inherited by the tasks enclosed by a block
気をつけること
今回の例のように、block
で指定したwhen
の条件が、そのblock
内で変化する場合、知らないとハマります
そうでない場合、知らなくても普通に使えちゃいますね・・・