问题描述
在使用Ansible时遇到了一个问题,他无法循环遍历字典中的列表,并保留原始字典的键。以下是他的数据示例:
vars:
nginx_users:
'instance1':
roles:
- product
- nginx_instance
cert_source: internal-ca
URL: page-nginx.domain.internal
port: 8090
downtime: true
basic_auth:
- username1
- username2
ip_restriction:
- '0.0.0.0/0'
'instance2':
roles:
- product
- nginx_instance
cert_source: internal-ca
URL: page2-nginx.domain.internal
port: 8091
downtime: true
basic_auth:
- username1
- username2
ip_restriction:
- '0.0.0.0/0'
'instance3':
roles:
- product
- nginx_instance
他希望以以下方式循环遍历:
"msg": [
"instance1",
[
"username1"
],
"instance1",
[
"username2"
],
"instance2",
[
"username1"
],
"instance2",
[
"username2"
]
...
]
他尝试使用以下代码:
...loop: "{{ nginx_users | dict2items }}"when: item.value.basic_auth is defined...
但是他不知道如何循环遍历这些”items”以获取每次迭代的用户列表并保留键。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
我们可以通过简化第一个任务中的字典,并在第二个任务中循环遍历子元素来解决这个问题。以下是任务的代码:
- set_fact:
nginx_users_selected: "{{ nginx_users_selected|
default({})|
combine({item.key: item.value}) }}"
loop: "{{ nginx_users|
dict2items|
json_query('[*].{key: key, value: value.basic_auth}') }}"
when: item.value
- debug:
msg: "{{ item.0.key }} {{ item.1 }}"
loop: "{{ nginx_users_selected|
dict2items|
subelements('value') }}"
这将输出:
"msg": "instance2 username1"
"msg": "instance2 username2"
"msg": "instance1 username1"
"msg": "instance1 username2"
然后,我们可以创建所需的结构:
- set_fact:
my_list: "{{ my_list|default([]) +
[ item.0.key, [ item.1 ]] }}"
loop: "{{ nginx_users_selected|
dict2items|
subelements('value') }}"
- debug:
var: my_list
这将输出:
"my_list": [
"instance2",
[
"username1"
],
"instance2",
[
"username2"
],
"instance1",
[
"username1"
],
"instance1",
[
"username2"
]
]
方案2
另一种方法是使用include_tasks
和内外循环来解决这个问题。以下是一个示例:
- include_tasks: loop_users.yml
loop: "{{ nginx_users | dict2items }}"
when: item.value.basic_auth is defined
在loop_users.yml
文件中,我们可以使用内外循环来实现所需的结果:
- debug:
msg: "{{ item.0.key }} {{ item.1 }}"
loop: "{{ item.value.basic_auth }}"
loop_control:
loop_var: inner_item
vars:
outer_item: "{{ item }}"
这将输出与方案1相同的结果。
希望这些解决方案对您有所帮助。如果您有任何其他问题,请随时提问。
正文完