I am trying to filter the following data based on the existence of username
within the sub dictionary.
An optimal solution would be, when I don't have to mention every single key e.g. agtsvcaccount, sqlsvcaccount, sapwd
, because this should be generic within other schemas.
This is an example input with the variable input_parameters
, this output is from an Ansible debug task.
ok: [localhost] => {
"msg": {
"ansible": {
"limit": [
"vm1234.vmdomain.com",
"vm5678.vmdomain.com"
]
},
"mssql": {
"edition": "standard",
"language": "en",
"setupconfig": {
"action": "Install",
"agtsvcaccount": {
"type": "System User",
"username": "SQL_Agt",
"vault": "credvault",
"visibility": false
},
"agtsvcstartuptype": "Automatic",
"features": [
"SQLENGINE"
],
"forcereboot": false,
"instancename": "MSSQLINSTANCE",
"npenabled": true,
"sapwd": {
"type": "Database",
"username": "sa",
"vault": "credvault",
"visibility": false
},
"securitymode": "SQL",
"sqlcollation": "SQL_Latin1_General_CP1_CI_AS",
"sqlsvcaccount": {
"type": "System User",
"username": "SQL_Svc",
"vault": "credvault",
"visibility": false
},
"sqlsvcstartuptype": "Automatic",
"sqlsysadminaccounts": [
"Administrator"
],
"tcpenabled": true
},
"version": "2022"
}
}
}
Right now, I am using something like this, which is not generic/dynamic enough, and i don't want to use account_identifiers
for other schematics, which are very similar.
- name: 'Process credentials'
ansible.builtin.include_role:
name: 'mycollection.generic'
tasks_from: 'user/{{ item.value.vault }}.yml'
loop: '{{ input_parameters.mssql.setupconfig | dict2items }}'
when: 'item.key in account_identifiers'
vars:
account_identifiers: ['sapwd','sqlsvcaccount','agtsvcaccount','ftsvcaccount','rssvcaccount','assvcaccount','issvcaccount']
Any ideas how to accomplish this?
I tried getting an idea from the Ansible documentation, but I think I'm missing something.
You can use selectattr
on the list of dictionaries created by your dict2items
, in order to test if a property of those dictionaries is defined.
So, your loop would ends up being:
loop: >-
{{
input_parameters.mssql.setupconfig
| dict2items
| selectattr('value.username', 'defined')
}}
With a simplified debug
task, on your input data:
- debug:
msg: "Username: {{ item.value.username }}"
loop_control:
label: "{{ item.key }}"
loop: >-
{{
input_parameters.mssql.setupconfig
| dict2items
| selectattr('value.username', 'defined')
}}
You would get:
ok: [localhost] => (item=agtsvcaccount) =>
msg: 'Username: SQL_Agt'
ok: [localhost] => (item=sapwd) =>
msg: 'Username: sa'
ok: [localhost] => (item=sqlsvcaccount) =>
msg: 'Username: SQL_Svc'