🫠
【Ansible】with_itemsとloopは同じ動作ではない。
公式サイトによれば、with_items:
はloop:
+ flatten(levels=1)
で置換できるとある。
ところが特定のデータを渡すと同じ動作をしなくてハマった。
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html#with-items
with_items is replaced by loop and the flatten filter.
- name: with_items
ansible.builtin.debug:
msg: "{{ item }}"
with_items: "{{ items }}"
- name: with_items -> loop
ansible.builtin.debug:
msg: "{{ item }}"
loop: "{{ items|flatten(levels=1) }}"
同じ動作にならないパターンを試す
まずVarsを用意する。
vars:
extra_items:
- src: "src_path_B"
dest: "dest_path_B"
Varsを組み込んだTaskを用意する。
- name: with_items
ansible.builtin.debug:
msg: "{{ item }}"
with_items:
- src: "src_path_A"
dest: "dest_path_A"
- "{{ extra_items }}"
- name: with_items -> loop
ansible.builtin.debug:
msg: "{{ item }}"
loop:
- src: "src_path_A"
dest: "dest_path_A"
- "{{ extra_items|flatten(levels=1) }}"
実行する。
- with_itemsの結果
ok: [localhost] => (item={'src': 'src_path_A', 'dest': 'dest_path_A'}) => {
"msg": {
"dest": "dest_path_A",
"src": "dest_path_A"
}
}
ok: [localhost] => (item={'dest': 'dest_path_B', 'src': 'src_path_B'}) => {
"msg": {
"dest": "dest_path_B",
"src": "dest_path_B"
}
}
- loopの結果 -> 変数参照している方だけ
[]
が付いたまま
ok: [localhost] => (item={'src': 'src_path_A', 'dest': 'dest_path_A'}) => {
"msg": {
"dest": "dest_path_B",
"src": "dest_path_B"
}
}
ok: [localhost] => (item=[{'dest': 'dest_path_A', 'src': 'src_path_A'}]) => {
"msg": [
{
"dest": "dest_path_A",
"src": "src_path_A"
}
]
このようにloopの方だと階層が狂うのでうまく動作しない。
listの中でlistが入った変数を読んでいるのでnested listになってしまう。
flattenで階層を揃えようとしてもなぜだか揃わない。
with_itemsを使った場合、nested listになっていてもよしなに階層を合わせてくれる。
with_Xは非推奨になっているわけではなく当面使えるとあるので、with_Xを使っておこう。
We have not deprecated the use of with_<lookup> - that syntax will still be valid for the foreseeable future.
Discussion