■ はじめに
Ansible 2.5 で with_* の代わりに利用できる loop キーワードが利用できるようになりました。
- 参考: 2.5.0 CHANGELOG
今まで with_items と同じと思い込んでいたのですが、そうではなく with_list と同じ、ということに気がついたのでまとめます。
違いは、一段階flatten(ネストを平らにして展開)されるか、されないかです。
| キーワード | flatten |
|---|---|
with_items |
一段階 flatten される |
with_list、loop |
flatten されない |
■ 検証
違いを確認するために、簡単な Playbook で検証します。
Playbook
- hosts: localhost gather_facts: no connection: local vars: testitems: - [1, 2] - 3 tasks: - name: with_items debug: msg: "{{ item }}" with_items: "{{ testitems }}" - name: with_list debug: msg: "{{ item }}" with_list: "{{ testitems }}" - name: normal loop debug: msg: "{{ item }}" loop: "{{ testitems }}"
実行結果
akira:~/environment $ ansible-playbook -i inventory looptest.yml PLAY [localhost] *********************************************** TASK [with_items] ********************************************** ok: [localhost] => (item=None) => { "msg": 1 } ok: [localhost] => (item=None) => { "msg": 2 } ok: [localhost] => (item=None) => { "msg": 3 } TASK [with_list] *********************************************** ok: [localhost] => (item=None) => { "msg": [ 1, 2 ] } ok: [localhost] => (item=None) => { "msg": 3 } TASK [normal loop] ********************************************* ok: [localhost] => (item=None) => { "msg": [ 1, 2 ] } ok: [localhost] => (item=None) => { "msg": 3 } PLAY RECAP ***************************************************** localhost : ok=3 changed=0 unreachable=0 failed=0
このように、 [[1, 2], 3] というネストされたリストが、
with_itemsは flatten されて、1、2、3という3回のループwith_listとloopは flatten されず、[1, 2]、3という2回のループ
になったことが確認できました。
with_items を loop で置き換えるなら、| flatten(levels=1) する
loop でも flatten フィルターを通すと flatten されて、 with_items と同じ動作になります。
- name: loop with flatten debug: msg: "{{ item }}" loop: "{{ testitems | flatten(levels=1) }}"
akira:~/environment $ ansible-playbook -i inventory looptest.yml
PLAY [localhost] ***********************************************
TASK [loop with flatten] ***************************************
ok: [localhost] => (item=None) => {
"msg": 1
}
ok: [localhost] => (item=None) => {
"msg": 2
}
ok: [localhost] => (item=None) => {
"msg": 3
}
PLAY RECAP ************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0
■ まとめ
通常の
loopは、with_listと同じく、 flatten されないフィルター
| flatten(levels=1)|を通すと、with_itemsと同じく一段階 flatten される
ということが分かりました。これから Playbook のサンプルは with_* ではなく、 loop が増えてくるのではないかと思います。
参考
Ansible 2.5 へのポーティングガイドで with_x から loop への以降方法が記載されています。
https://docs.ansible.com/ansible/latest/porting_guides/porting_guide_2.5.html#migrating-from-with-x-to-loop