Nested loops with multiple variables ansible

Viewed 35

So I have a variable file that looks like this:

etherchannels:
  channel1:
     - groupid: 1
       mode: on
       members:
         - Ethernet1/0
         - Ethernet1/2
  channel2:
     - groupid: 2
       mode: on
       members:
         - Ethernet2/0
         - Ethernet2/2

and I want to pass it into something like this:

  tasks:
  - name: configure etherchannel
    cisco.ios.ios_lag_interfaces:
      config:
      - name: Port-channel{{ item.groupid }}
        members:
        - member: "{{ item.member }}"
          mode: "{{ item.mode }}"
    loop: "{{ etherchannels }}"

My expected outcome should be something like this:

Channel 1:
name: portchannel1
members:
  - member: Ethernet1/0
    mode: on
  - member: Ethernet1/1
    mode:on

Channel 2:
name: portchannel2
members:
  - member: Ethernet2/0
    mode: on
  - member: Ethernet2/1
    mode:on

I'm stuck trying to figure out how to loop through the members variables without having to manually add a member and mode line for every interfaces.

1 Answers

See community.general dictionaries. For example, the playbook

- hosts: localhost

  vars:

    etherchannels:
      channel1:
        - groupid: 1
          mode: on
          members:
            - Ethernet1/0
            - Ethernet1/2
      channel2:
        - groupid: 2
          mode: on
          members:
            - Ethernet2/0
            - Ethernet2/2

  tasks:

    - debug:
        msg: |
          name: {{ _name }}
          members:
            {{ _members|to_yaml|indent(2) }}
      loop: "{{ etherchannels|dict2items }}"
      loop_control:
        label: "{{ item.key }}"
      vars:
        _name: "portchannel{{ item.value.0.groupid }}"
        _members: "{{ item.value.0.members|
                      map('community.general.dict_kv', 'member')|
                      map('combine', {'mode': item.value.0.mode})|list }}"

gives (abridged)

ok: [localhost] => (item=channel1) => 
  msg: |-
    name: portchannel1
    members:
      - {member: Ethernet1/0, mode: true}
      - {member: Ethernet1/2, mode: true}
ok: [localhost] => (item=channel2) => 
  msg: |-
    name: portchannel2
    members:
      - {member: Ethernet2/0, mode: true}
      - {member: Ethernet2/2, mode: true}
Related