How to solve this specific nested loop in Ansible?

Viewed 1116

We have two lists. Which can have any amount of items.

vrfs:
 - name: vrf1
   id: 11
 - name: vrf2
   id: 12
 - name: vrf3
   id: 13

interfaces:
 - vlan
 - gigabit1.

And we have a task with a loop, in which we want to combine these lists, separately, based on the ID of vrfs list and use this same ID and name in the task as well so the output would be in each loop cycle as follows:

1st cycle:
11
vrf1
vlan11
gigabit1.11

2nd cycle:
12
vrf2
vlan12
gigabit1.12

3rd cycle:
13
vrf3
vlan13
gigabit1.13

I have tried all kinds of nested loop variations so far, but none achieve the described outcome, because in the usual nested loop:

loop: "{{ vrfs|product(interfaces)|list }}"

Everything is iterated one by one, meaning we first iterate item 1 of vrfs & item 1 of interfaces, but I need to iterate all items of the interfaces list at once in the inner loop.

inclue_tasks would solve this, since I could combine the IDs and interfaces into a temporary list variable in the inner loop in one shot, with something like this:

- 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 }}"

But I can not run include_tasks and the other module I need to use in outer loop.

Any ideas?

2 Answers

For example

    - 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

gives

  msg: |-
    cycle No1
    11
    vrf1
    vlan11
    gigabit1.11

  msg: |-
    cycle No2
    12
    vrf2
    vlan12
    gigabit1.12

  msg: |-
    cycle No3
    13
    vrf3
    vlan13
    gigabit1.13

Figured it out.

include_tasks inner loop was the answer.

The solution looks like this:

- 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 }}"
Related