HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Traverse nested dictionary with keeping the keys in ansible

Submitted by: @import:stackexchange-devops··
0
Viewed 0 times
keepingthewithtraversenestedkeysdictionaryansible

Problem

I'm not able to loop a list in a dict and keep the key of the original dict.

Bellow an example of my data

vars:
 nginx_users:
    'instance1':
       roles:
          - product
          - nginx_instance
       cert_source: internal-ca
       URL: page-nginx.domain.internal
       port: 8090
       downtime: true
       basic_auth:
          - username1
          - username2
       ip_restriction:
          - '0.0.0.0/0'
    'instance2':
       roles:
          - product
          - nginx_instance
       cert_source: internal-ca
       URL: page2-nginx.domain.internal
       port: 8091
       downtime: true
       basic_auth:
          - username1
          - username2
       ip_restriction:
          - '0.0.0.0/0'
    'instance3':
       roles:
          - product
          - nginx_instance


I need to loop it in a manner that It iterates like this

"msg": [
        "instance1",
        [
            "username1"
        ],
        "instance1",
        [
            "username2"
        ],
       "instance2",
        [
            "username1"
        ],
        "instance2",
        [
            "username2"
        ]
...
    ]


I am using


when: item.value.basic_auth is defined

In a loop which will filter out the items without the desired value/item and return only the "items" that I need to parse, like.

...
loop: "{{ nginx_users | dict2items }}"
when: item.value.basic_auth is defined
...


However from there I don't know how to loop those "items" to get the list of users on a way that it returns the single user per iteration and preserve the key.

I know a work around would be to have use another variable instead of the key so I could just select it. but that wouldn't work for me in this escenario.

I have tried using subelements and lookup but I don't seem to be able narrow down the exact combination also thought about using product too and try and traverse the data. But I wasn't able to use that either.

After reading this:

https://gi

Solution

Let's simplify the dictionary in the first task and loop the subelements in the second. The tasks below
- set_fact:
nginx_users_selected: "{{ nginx_users_selected|
default({})|
combine({item.key: item.value})
}}"
loop: "{{ nginx_users|
dict2items|
json_query('[*].{key: key, value: value.basic_auth}')
}}"
when: item.value
- debug:
msg: "{{ item.0.key }} {{ item.1 }}"
loop: "{{ nginx_users_selected|
dict2items|
subelements('value')
}}"


give
"msg": "instance2 username1"
"msg": "instance2 username2"
"msg": "instance1 username1"
"msg": "instance1 username2"


Then we can create the structure
- set_fact:
my_list: "{{ my_list|default([]) +
[ item.0.key, [ item.1 ]] }}"
loop: "{{ nginx_users_selected|
dict2items|
subelements('value') }}"
- debug:
var: my_list


give
"my_list": [
"instance2",
[
"username1"
],
"instance2",
[
"username2"
],
"instance1",
[
"username1"
],
"instance1",
[
"username2"
]
]

Context

StackExchange DevOps Q#8609, answer score: 3

Revisions (0)

No revisions yet.