Search code examples
loopsansiblecisco

Looping through complex dictionary with Ansible


I'm using the Cisco ACI_REST module. I'm building a playbook to shutdown all of my ACI EPGs. The ACI_EPG module is used to create the dict.

- name: Get List of EPGs
       cisco.aci.aci_epg:
         host: "{{ inventory_hostname }}"
         username: "{{ ansible_user }}"
         password: "{{ ansible_password }}"
         validate_certs: no
         state: query
       delegate_to: localhost
       register: epg_list

It creates a dictionary that looks like this:

  "item": {
        "key": "current",
        "value": [
            {
                "fvAEPg": {
                    "attributes": {
                        "dn": "uni/tn-PC/ap-PROD_AP/epg-VLAN80_EPG",
                        "shutdown": "no",
                     },
                    "children": [
                        {
                            "fvRsBd": {
                                "attributes": {
                                    "annotation": "",
                                    "tDn": "uni/tn-PC/BD-VLAN80_BD",
                                    "tRn": "BD-VLAN80_BD",
                                    "tType": "name",
                                    "tnFvBDName": "VLAN80_BD",
                                    "uid": "0"
                                },
                                "children": [
                                    {
                                        "fvSubnetBDDefCont": {
                                            "attributes": {
                                                "name": "",
                                                "nameAlias": "",
                                                "status": ""
                                            }
                                        }
                                    }
                                ]
                            }
                        }
                    ]
                }
            }

I need to loop through the DN values.

"dn": "uni/tn-PC/ap-PROD_AP/epg-VLAN80_EPG"

I'm playing with dict2items but am stuck. How to I reference the nested items in my dictionary? Here is some test code that I'm working with.

- name: Display EPG List
       ansible.builtin.debug:
         msg: "{{ item.key }} - {{ item.value }}"
       loop: "{{ epg_list | dict2items }}"  

Thanks,


Solution

  • Q: "Loop through the DN values."

    A: Try json_query, e.g.

        - debug:
            msg: "{{ item }}"
          loop: "{{ epg_list.item.value|
                    json_query('[].*.attributes.dn')|
                    flatten }}"
    

    gives

      msg: uni/tn-PC/ap-PROD_AP/epg-VLAN80_EPG
    

    Given the data

      epg_list:
        item:
          key: current
          value:
          - fvAEPg:
              attributes:
                dn: uni/tn-PC/ap-PROD_AP/epg-VLAN80_EPG
                shutdown: 'no'
              children:
              - fvRsBd:
                  attributes:
                    annotation: ''
                    tDn: uni/tn-PC/BD-VLAN80_BD
                    tRn: BD-VLAN80_BD
                    tType: name
                    tnFvBDName: VLAN80_BD
                    uid: '0'
                  children:
                  - fvSubnetBDDefCont:
                      attributes:
                        name: ''
                        nameAlias: ''
                        status: ''
    

    If the data is

      epg_list:
        current:
        - fvAEPg:
            attributes:
              dn: uni/tn-PC/ap-PROD_AP/epg-VLAN80_EPG
              shutdown: 'no'
            children:
            - fvRsBd:
                attributes:
                  annotation: ''
                  tDn: uni/tn-PC/BD-VLAN80_BD
                  tRn: BD-VLAN80_BD
                  tType: name
                  tnFvBDName: VLAN80_BD
                  uid: '0'
                children:
                - fvSubnetBDDefCont:
                    attributes:
                      name: ''
                      nameAlias: ''
                      status: ''
    

    the task below gives the same result

        - debug:
            msg: "{{ item }}"
          loop: "{{ epg_list.current|
                    json_query('[].*.attributes.dn')|
                    flatten }}"