如何在 Ansible 中解决这个特定的嵌套循环?
How to solve this specific nested loop in Ansible?
我们有两个列表。其中可以有任意数量的项目。
vrfs:
- name: vrf1
id: 11
- name: vrf2
id: 12
- name: vrf3
id: 13
interfaces:
- vlan
- gigabit1.
我们有一个带有循环的任务,我们希望根据 vrfs 列表的 ID 分别组合这些列表,并在任务中使用相同的 ID 和名称,因此输出将在每个loop循环如下:
1st cycle:
11
vrf1
vlan11
gigabit1.11
2nd cycle:
12
vrf2
vlan12
gigabit1.12
3rd cycle:
13
vrf3
vlan13
gigabit1.13
到目前为止,我已经尝试了各种嵌套循环变体,但是 none 实现了描述的结果,因为在通常的嵌套循环中:
loop: "{{ vrfs|product(interfaces)|list }}"
一切都被一个接一个地迭代,这意味着我们首先迭代 vrfs 的第 1 项和接口的第 1 项,但是我需要在内循环中一次迭代接口列表的所有项。
inclue_tasks 会解决这个问题,因为我可以一次性将 ID 和接口组合到内部循环中的一个临时列表变量中,像这样:
- name: Initialize an empty list
set_fact:
interfaces_combined: []
- name: Combine interface prefixes with VRF IDs
set_fact:
interfaces_combined: "{{ interfaces_combined + [ item + outer.item.id|string ] }}"
loop: "{{ interfaces }}"
但是我不能运行 include_tasks和我需要在外循环中使用的其他模块。
有什么想法吗?
想通了。
include_tasks 内循环就是答案。
解决方案如下所示:
- name: Configure interfaces into VRFs (outer loop)
include_tasks: int_vrf_inner.yml
loop: "{{ vrfs }}"
loop_control:
loop_var: outer_item
int_vrf_inner.yml:
- name: Initialize an empty list
set_fact:
interfaces_combined: []
- name: Combine interface prefixes with VRF IDs
set_fact:
interfaces_combined: "{{ interfaces_combined + [ item + outer_item.id|string ] }}"
loop: "{{ interfaces }}"
- name: Configure interfaces into VRFs (inner loop)
cisco.ios.ios_vrf:
name: "{{ outer_item.name }}"
interfaces:
"{{ interfaces_combined }}"
例如
- debug:
msg: |
cycle No{{ansible_loop.index}}
{{ item.id }}
{{ item.name }}
{% for i in interfaces %}
{{ i }}{{ item.id }}
{% endfor %}
loop: "{{ vrfs }}"
loop_control:
extended: true
给予
msg: |-
cycle No1
11
vrf1
vlan11
gigabit1.11
msg: |-
cycle No2
12
vrf2
vlan12
gigabit1.12
msg: |-
cycle No3
13
vrf3
vlan13
gigabit1.13
我们有两个列表。其中可以有任意数量的项目。
vrfs:
- name: vrf1
id: 11
- name: vrf2
id: 12
- name: vrf3
id: 13
interfaces:
- vlan
- gigabit1.
我们有一个带有循环的任务,我们希望根据 vrfs 列表的 ID 分别组合这些列表,并在任务中使用相同的 ID 和名称,因此输出将在每个loop循环如下:
1st cycle:
11
vrf1
vlan11
gigabit1.11
2nd cycle:
12
vrf2
vlan12
gigabit1.12
3rd cycle:
13
vrf3
vlan13
gigabit1.13
到目前为止,我已经尝试了各种嵌套循环变体,但是 none 实现了描述的结果,因为在通常的嵌套循环中:
loop: "{{ vrfs|product(interfaces)|list }}"
一切都被一个接一个地迭代,这意味着我们首先迭代 vrfs 的第 1 项和接口的第 1 项,但是我需要在内循环中一次迭代接口列表的所有项。
inclue_tasks 会解决这个问题,因为我可以一次性将 ID 和接口组合到内部循环中的一个临时列表变量中,像这样:
- name: Initialize an empty list
set_fact:
interfaces_combined: []
- name: Combine interface prefixes with VRF IDs
set_fact:
interfaces_combined: "{{ interfaces_combined + [ item + outer.item.id|string ] }}"
loop: "{{ interfaces }}"
但是我不能运行 include_tasks和我需要在外循环中使用的其他模块。
有什么想法吗?
想通了。
include_tasks 内循环就是答案。
解决方案如下所示:
- name: Configure interfaces into VRFs (outer loop)
include_tasks: int_vrf_inner.yml
loop: "{{ vrfs }}"
loop_control:
loop_var: outer_item
int_vrf_inner.yml:
- name: Initialize an empty list
set_fact:
interfaces_combined: []
- name: Combine interface prefixes with VRF IDs
set_fact:
interfaces_combined: "{{ interfaces_combined + [ item + outer_item.id|string ] }}"
loop: "{{ interfaces }}"
- name: Configure interfaces into VRFs (inner loop)
cisco.ios.ios_vrf:
name: "{{ outer_item.name }}"
interfaces:
"{{ interfaces_combined }}"
例如
- debug:
msg: |
cycle No{{ansible_loop.index}}
{{ item.id }}
{{ item.name }}
{% for i in interfaces %}
{{ i }}{{ item.id }}
{% endfor %}
loop: "{{ vrfs }}"
loop_control:
extended: true
给予
msg: |-
cycle No1
11
vrf1
vlan11
gigabit1.11
msg: |-
cycle No2
12
vrf2
vlan12
gigabit1.12
msg: |-
cycle No3
13
vrf3
vlan13
gigabit1.13