如何使用with_nested遍历两种不同类型的Ansible列表/字典变量?
Ansible分离列表变量的遍历实现
问题背景
现有Ansible Playbook可处理嵌套结构的volumes变量,但无法处理分离的独立列表变量:
- 可处理的嵌套变量结构:
volumes: - volumename: volume1 client: - 1.1.1.1 - 1.1.1.2 - volumename: volume2 client: - 2.2.2.2 - volumename: volume3 client: - 3.3.3.3
- 无法处理的分离列表结构:
vars: volumename: - volume1 - volume2 - volume3 client: - 1.1.1.1 - 1.1.1.2
期望输出所有卷名与客户端的组合:
volume1 --> 1.1.1.1 volume2 --> 1.1.1.1 volume3 --> 1.1.1.1 volume1 --> 1.1.1.2 volume2 --> 1.1.1.2 volume3 --> 1.1.1.2
之前尝试错误的with_nested写法:
with_nested: - "{{ volumes|subelements('client') }}" - "{{ volumes|subelements('volumename') }}"
错误原因:subelements过滤器仅适用于嵌套结构,而第二种变量是两个独立列表,不需要该过滤器。
解决方案
要实现两个独立列表的笛卡尔积遍历,直接使用with_nested(或Ansible 2.5+推荐的loop配合query('nested'))即可,不需要额外过滤器。
方法1:使用with_nested
- name: print volumes (separated lists) hosts: localhost vars: volumename: - volume1 - volume2 - volume3 client: - 1.1.1.1 - 1.1.1.2 tasks: - name: display volume-client combinations debug: msg: "{{ item.0 }} --> {{ item.1 }}" with_nested: - "{{ volumename }}" - "{{ client }}" loop_control: label: "{{ item.0 }} - {{ item.1 }}"
方法2:使用loop + query('nested')(推荐)
- name: print volumes (separated lists) hosts: localhost vars: volumename: - volume1 - volume2 - volume3 client: - 1.1.1.1 - 1.1.1.2 tasks: - name: display volume-client combinations debug: msg: "{{ item.0 }} --> {{ item.1 }}" loop: "{{ query('nested', volumename, client) }}" loop_control: label: "{{ item.0 }} - {{ item.1 }}"
输出验证
执行上述Playbook后,将得到符合期望的输出:
ok: [localhost] => (item=volume1 - 1.1.1.1) => { "msg": "volume1 --> 1.1.1.1" } ok: [localhost] => (item=volume1 - 1.1.1.2) => { "msg": "volume1 --> 1.1.1.2" } ok: [localhost] => (item=volume2 - 1.1.1.1) => { "msg": "volume2 --> 1.1.1.1" } ok: [localhost] => (item=volume2 - 1.1.1.2) => { "msg": "volume2 --> 1.1.1.2" } ok: [localhost] => (item=volume3 - 1.1.1.1) => { "msg": "volume3 --> 1.1.1.1" } ok: [localhost] => (item=volume3 - 1.1.1.2) => { "msg": "volume3 --> 1.1.1.2" }
内容的提问来源于stack exchange,提问作者gang
相关产品推荐
相关产品推荐

