Ansible 字典嵌套循环
Ansible Dictionary Nested For Loop
我以前尝试过使用这样的字典结构,但只在模板中使用过。我需要遍历 servers
中不匹配 inventory_hostname
.
的所有 subnets/subnet_cidrs 一级键
---
- name: Test Playbook
hosts: localhost
gather_facts: no
vars:
servers:
alpha.lan:
eth0:
subnet: 192.168.0.0
subnet_mask: 255.255.255.0
subnet_cidr: 24
eth1:
subnet: 192.168.1.0
subnet_mask: 255.255.255.0
subnet_cidr: 24
bravo.lan:
eth0:
subnet: 172.16.0.0
subnet_mask: 255.255.252.0
subnet_cidr: 22
eth1:
subnet: 172.16.4.0
subnet_mask: 255.255.252.0
subnet_cidr: 22
tasks:
- debug:
msg: "{{something['subnet']}}/{{something['subnet_cidr']}}"
loop: "{{servers...}}"
所以如果这个剧本是 运行 alpha.lan 我会得到
"msg": "172.16.0.0/22"
"msg": "172.16.4.0/22"
这就是我如何让它在模板中工作,能够在最终输出中使用 item 和 item2 的值:
{% for key,item in servers.items() if key != inventory_hostname %}
{% for key2,item2 in item.items() %}
{{item2['subnet']}}/{{item2['subnet_cidr']}}
{% endfor %}
{% endfor %}
我希望能够在防火墙命令中独立使用或测试每个三级密钥(子网、subnet_mask、subnet_cidr)。在此先感谢您的帮助。
我尝试使用的一些信息源:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html
https://jinja.palletsprojects.com/en/2.11.x/templates/#list-of-builtin-filters
给定字典服务器剧本
- hosts: alpha.lan,bravo.lan
tasks:
- debug:
msg: "{{ item.value.subnet }}/{{ item.value.subnet_cidr }}"
loop: "{{ servers[host]|dict2items }}"
loop_control:
label: "{{ item.key }}"
vars:
host: "{{ servers|difference([inventory_hostname])|first }}"
给出(删节)
TASK [debug] ****
ok: [alpha.lan] => (item=eth0) =>
msg: 172.16.0.0/22
ok: [alpha.lan] => (item=eth1) =>
msg: 172.16.4.0/22
ok: [bravo.lan] => (item=eth0) =>
msg: 192.168.0.0/24
ok: [bravo.lan] => (item=eth1) =>
msg: 192.168.1.0/24
问:"一级键列表,...遍历服务器...同时遍历每个服务器的二级键"
给定字典
servers:
alpha.lan:
eth0:
subnet: 192.168.0.0
subnet_cidr: 24
eth1:
subnet: 192.168.1.0
subnet_cidr: 24
bravo.lan:
eth0:
subnet: 172.16.0.0
subnet_cidr: 22
eth1:
subnet: 172.16.4.0
subnet_cidr: 22
charlie.lan:
eth0:
subnet: 172.17.0.0
subnet_cidr: 22
eth1:
subnet: 172.17.4.0
subnet_cidr: 22
和任务
shell> cat loop-net.yml
- debug:
msg: "inventory: {{ inventory_hostname }}
server: {{ outer_item }}
net: {{ item.value.subnet }}/{{ item.value.subnet_cidr }}"
loop: "{{ servers[outer_item]|dict2items }}"
loop_control:
label: "{{ item.key }}"
下面的剧本
shell> cat pb.yml
- hosts: alpha.lan,bravo.lan,charlie.lan
tasks:
- include_tasks: loop-net.yml
loop: "{{ servers.keys()|difference([inventory_hostname]) }}"
loop_control:
loop_var: outer_item
给予
shell> ansible-playbook pb.yml | grep msg | sort
msg: 'inventory: alpha.lan server: bravo.lan net: 172.16.0.0/22'
msg: 'inventory: alpha.lan server: bravo.lan net: 172.16.4.0/22'
msg: 'inventory: alpha.lan server: charlie.lan net: 172.17.0.0/22'
msg: 'inventory: alpha.lan server: charlie.lan net: 172.17.4.0/22'
msg: 'inventory: bravo.lan server: alpha.lan net: 192.168.0.0/24'
msg: 'inventory: bravo.lan server: alpha.lan net: 192.168.1.0/24'
msg: 'inventory: bravo.lan server: charlie.lan net: 172.17.0.0/22'
msg: 'inventory: bravo.lan server: charlie.lan net: 172.17.4.0/22'
msg: 'inventory: charlie.lan server: alpha.lan net: 192.168.0.0/24'
msg: 'inventory: charlie.lan server: alpha.lan net: 192.168.1.0/24'
msg: 'inventory: charlie.lan server: bravo.lan net: 172.16.0.0/22'
msg: 'inventory: charlie.lan server: bravo.lan net: 172.16.4.0/22'
下面的任务给出了相同的结果
- debug:
msg: "inventory: {{ inventory_hostname }}
server: {{ item.0.key }}
net: {{ item.1.net }}"
with_subelements:
- "{{ my_servers|from_yaml|dict2items }}"
- value
vars:
my_servers: |
{% for key,item in servers.items() if key != inventory_hostname %}
{{ key }}:
{% for key2,item2 in item.items() %}
- {ifc: {{ key2 }}, net: {{ item2.subnet }}/{{ item2.subnet_cidr }}}
{% endfor %}
{% endfor %}
我以前尝试过使用这样的字典结构,但只在模板中使用过。我需要遍历 servers
中不匹配 inventory_hostname
.
---
- name: Test Playbook
hosts: localhost
gather_facts: no
vars:
servers:
alpha.lan:
eth0:
subnet: 192.168.0.0
subnet_mask: 255.255.255.0
subnet_cidr: 24
eth1:
subnet: 192.168.1.0
subnet_mask: 255.255.255.0
subnet_cidr: 24
bravo.lan:
eth0:
subnet: 172.16.0.0
subnet_mask: 255.255.252.0
subnet_cidr: 22
eth1:
subnet: 172.16.4.0
subnet_mask: 255.255.252.0
subnet_cidr: 22
tasks:
- debug:
msg: "{{something['subnet']}}/{{something['subnet_cidr']}}"
loop: "{{servers...}}"
所以如果这个剧本是 运行 alpha.lan 我会得到
"msg": "172.16.0.0/22"
"msg": "172.16.4.0/22"
这就是我如何让它在模板中工作,能够在最终输出中使用 item 和 item2 的值:
{% for key,item in servers.items() if key != inventory_hostname %}
{% for key2,item2 in item.items() %}
{{item2['subnet']}}/{{item2['subnet_cidr']}}
{% endfor %}
{% endfor %}
我希望能够在防火墙命令中独立使用或测试每个三级密钥(子网、subnet_mask、subnet_cidr)。在此先感谢您的帮助。
我尝试使用的一些信息源:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html
https://jinja.palletsprojects.com/en/2.11.x/templates/#list-of-builtin-filters
给定字典服务器剧本
- hosts: alpha.lan,bravo.lan
tasks:
- debug:
msg: "{{ item.value.subnet }}/{{ item.value.subnet_cidr }}"
loop: "{{ servers[host]|dict2items }}"
loop_control:
label: "{{ item.key }}"
vars:
host: "{{ servers|difference([inventory_hostname])|first }}"
给出(删节)
TASK [debug] ****
ok: [alpha.lan] => (item=eth0) =>
msg: 172.16.0.0/22
ok: [alpha.lan] => (item=eth1) =>
msg: 172.16.4.0/22
ok: [bravo.lan] => (item=eth0) =>
msg: 192.168.0.0/24
ok: [bravo.lan] => (item=eth1) =>
msg: 192.168.1.0/24
问:"一级键列表,...遍历服务器...同时遍历每个服务器的二级键"
给定字典
servers:
alpha.lan:
eth0:
subnet: 192.168.0.0
subnet_cidr: 24
eth1:
subnet: 192.168.1.0
subnet_cidr: 24
bravo.lan:
eth0:
subnet: 172.16.0.0
subnet_cidr: 22
eth1:
subnet: 172.16.4.0
subnet_cidr: 22
charlie.lan:
eth0:
subnet: 172.17.0.0
subnet_cidr: 22
eth1:
subnet: 172.17.4.0
subnet_cidr: 22
和任务
shell> cat loop-net.yml
- debug:
msg: "inventory: {{ inventory_hostname }}
server: {{ outer_item }}
net: {{ item.value.subnet }}/{{ item.value.subnet_cidr }}"
loop: "{{ servers[outer_item]|dict2items }}"
loop_control:
label: "{{ item.key }}"
下面的剧本
shell> cat pb.yml
- hosts: alpha.lan,bravo.lan,charlie.lan
tasks:
- include_tasks: loop-net.yml
loop: "{{ servers.keys()|difference([inventory_hostname]) }}"
loop_control:
loop_var: outer_item
给予
shell> ansible-playbook pb.yml | grep msg | sort
msg: 'inventory: alpha.lan server: bravo.lan net: 172.16.0.0/22'
msg: 'inventory: alpha.lan server: bravo.lan net: 172.16.4.0/22'
msg: 'inventory: alpha.lan server: charlie.lan net: 172.17.0.0/22'
msg: 'inventory: alpha.lan server: charlie.lan net: 172.17.4.0/22'
msg: 'inventory: bravo.lan server: alpha.lan net: 192.168.0.0/24'
msg: 'inventory: bravo.lan server: alpha.lan net: 192.168.1.0/24'
msg: 'inventory: bravo.lan server: charlie.lan net: 172.17.0.0/22'
msg: 'inventory: bravo.lan server: charlie.lan net: 172.17.4.0/22'
msg: 'inventory: charlie.lan server: alpha.lan net: 192.168.0.0/24'
msg: 'inventory: charlie.lan server: alpha.lan net: 192.168.1.0/24'
msg: 'inventory: charlie.lan server: bravo.lan net: 172.16.0.0/22'
msg: 'inventory: charlie.lan server: bravo.lan net: 172.16.4.0/22'
下面的任务给出了相同的结果
- debug:
msg: "inventory: {{ inventory_hostname }}
server: {{ item.0.key }}
net: {{ item.1.net }}"
with_subelements:
- "{{ my_servers|from_yaml|dict2items }}"
- value
vars:
my_servers: |
{% for key,item in servers.items() if key != inventory_hostname %}
{{ key }}:
{% for key2,item2 in item.items() %}
- {ifc: {{ key2 }}, net: {{ item2.subnet }}/{{ item2.subnet_cidr }}}
{% endfor %}
{% endfor %}