带有字典列表的 Ansible 循环
Ansible loop with a list in a dict
我正在寻找将列表循环到字典中的方法,但无法找到 loop
/with_*
等方法,而无需重新处理我的栏。
如果有人给我小费,我会很高兴!
这是我的酒吧:
apps:
- app1
- app2
- app3
我的设置:
settings:
app1:
url: myself
arg1: value1
arg2: value2
app2:
arg8: value32
arg38: value00
app3:
arg42: /bin/false
我想为每个应用程序的每个参数执行一个命令。
所以我的解决方案是将列表和字典转换为:
settings:
- name: app1
arg: url
value: myself
- name: app1
arg: arg1
value: value1
- name: app1
arg: arg2
value: value2
- name: app2
arg: ...
然后在此列表上执行 with_items
并使用名称 arg 和值执行我的命令。
这是唯一的解决方案吗?
这可以通过 Ansible 提供的 set_fact
, listing all the arguments of an application, then using the subelement
Jinja 过滤器来实现,以根据创建的事实创建命令。
鉴于剧本:
- hosts: all
gather_facts: no
vars:
settings:
app1:
url: myself
arg1: value1
arg2: value2
app2:
arg8: value32
arg38: value00
app3:
arg42: /bin/false
tasks:
##
# This `set_fact` build this list [
# {"name": "app1", "args": ["url", "arg1", "arg2"]},
# {"name": "app2", "args": ["arg8", "arg38"]},
# {"name": "app2", "args": ["arg42"]}
# ]
##
- set_fact:
app_args: |-
{{
app_args | default([]) +
[ {'name': item, 'args': settings[item].keys() | list} ]
}}
loop: "{{ settings.keys() }}"
- debug:
msg: >-
some_command {{ item.0.name }}
--{{ item.1 }}={{ settings[item.0.name][item.1] }}
loop: "{{ app_args | subelements('args') }}"
哪个会产生重述:
PLAY [all] *******************************************************************************************************
TASK [set_fact] **************************************************************************************************
ok: [localhost] => (item=app1)
ok: [localhost] => (item=app2)
ok: [localhost] => (item=app3)
TASK [debug] *****************************************************************************************************
ok: [localhost] => (item=[{'name': 'app1', 'args': ['url', 'arg1', 'arg2']}, 'url']) => {
"msg": "some_command app1 --url=myself"
}
ok: [localhost] => (item=[{'name': 'app1', 'args': ['url', 'arg1', 'arg2']}, 'arg1']) => {
"msg": "some_command app1 --arg1=value1"
}
ok: [localhost] => (item=[{'name': 'app1', 'args': ['url', 'arg1', 'arg2']}, 'arg2']) => {
"msg": "some_command app1 --arg2=value2"
}
ok: [localhost] => (item=[{'name': 'app2', 'args': ['arg8', 'arg38']}, 'arg8']) => {
"msg": "some_command app2 --arg8=value32"
}
ok: [localhost] => (item=[{'name': 'app2', 'args': ['arg8', 'arg38']}, 'arg38']) => {
"msg": "some_command app2 --arg38=value00"
}
ok: [localhost] => (item=[{'name': 'app3', 'args': ['arg42']}, 'arg42']) => {
"msg": "some_command app3 --arg42=/bin/false"
}
PLAY RECAP *******************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
我正在寻找将列表循环到字典中的方法,但无法找到 loop
/with_*
等方法,而无需重新处理我的栏。
如果有人给我小费,我会很高兴!
这是我的酒吧:
apps:
- app1
- app2
- app3
我的设置:
settings:
app1:
url: myself
arg1: value1
arg2: value2
app2:
arg8: value32
arg38: value00
app3:
arg42: /bin/false
我想为每个应用程序的每个参数执行一个命令。
所以我的解决方案是将列表和字典转换为:
settings:
- name: app1
arg: url
value: myself
- name: app1
arg: arg1
value: value1
- name: app1
arg: arg2
value: value2
- name: app2
arg: ...
然后在此列表上执行 with_items
并使用名称 arg 和值执行我的命令。
这是唯一的解决方案吗?
这可以通过 Ansible 提供的 set_fact
, listing all the arguments of an application, then using the subelement
Jinja 过滤器来实现,以根据创建的事实创建命令。
鉴于剧本:
- hosts: all
gather_facts: no
vars:
settings:
app1:
url: myself
arg1: value1
arg2: value2
app2:
arg8: value32
arg38: value00
app3:
arg42: /bin/false
tasks:
##
# This `set_fact` build this list [
# {"name": "app1", "args": ["url", "arg1", "arg2"]},
# {"name": "app2", "args": ["arg8", "arg38"]},
# {"name": "app2", "args": ["arg42"]}
# ]
##
- set_fact:
app_args: |-
{{
app_args | default([]) +
[ {'name': item, 'args': settings[item].keys() | list} ]
}}
loop: "{{ settings.keys() }}"
- debug:
msg: >-
some_command {{ item.0.name }}
--{{ item.1 }}={{ settings[item.0.name][item.1] }}
loop: "{{ app_args | subelements('args') }}"
哪个会产生重述:
PLAY [all] *******************************************************************************************************
TASK [set_fact] **************************************************************************************************
ok: [localhost] => (item=app1)
ok: [localhost] => (item=app2)
ok: [localhost] => (item=app3)
TASK [debug] *****************************************************************************************************
ok: [localhost] => (item=[{'name': 'app1', 'args': ['url', 'arg1', 'arg2']}, 'url']) => {
"msg": "some_command app1 --url=myself"
}
ok: [localhost] => (item=[{'name': 'app1', 'args': ['url', 'arg1', 'arg2']}, 'arg1']) => {
"msg": "some_command app1 --arg1=value1"
}
ok: [localhost] => (item=[{'name': 'app1', 'args': ['url', 'arg1', 'arg2']}, 'arg2']) => {
"msg": "some_command app1 --arg2=value2"
}
ok: [localhost] => (item=[{'name': 'app2', 'args': ['arg8', 'arg38']}, 'arg8']) => {
"msg": "some_command app2 --arg8=value32"
}
ok: [localhost] => (item=[{'name': 'app2', 'args': ['arg8', 'arg38']}, 'arg38']) => {
"msg": "some_command app2 --arg38=value00"
}
ok: [localhost] => (item=[{'name': 'app3', 'args': ['arg42']}, 'arg42']) => {
"msg": "some_command app3 --arg42=/bin/false"
}
PLAY RECAP *******************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0