I query some information from cisco apic controller and I cutout the necessary information using json_query
filter as follows:
set_fact:
my_nodes: "{{ my_nodes| json_query('current[*].fabricNodeIdentP.attributes.{node_name: name, node_id: nodeId, pod_id:podId}') }}"
Result is the following JSON formatted data:
"my_nodes": [
{
"node_id": "1",
"node_name": "node01",
"pod_id": "1"
},
{
"node_id": "2",
"node_name": "node02",
"pod_id": "1"
},
{
"node_id": "3",
"node_name": "node03",
"pod_id": "1"
}
]
What I want to have/achieve is, to have node_name
as the main data object which should look like this:
{
"node01":
{
"node_id": "1",
"pod_id": "1"
},
"node02":
{
"node_id": "2",
"pod_id": "1"
},
"node03":
{
"node_id": "3",
"pod_id": "1"
}
}
I've tried to use the combine
filter but I could only add a new key:value pair with it. Is there any way to achieve thin in ansible?
Put the declarations as appropriate
my_nodes_keys: "{{ my_nodes|map(attribute='node_name')|list }}"
my_nodes_dict: "{{ dict(my_nodes_keys|zip(my_nodes)) }}"
gives
my_nodes_dict:
node01:
node_id: '1'
node_name: node01
pod_id: '1'
node02:
node_id: '2'
node_name: node02
pod_id: '1'
node03:
node_id: '3'
node_name: node03
pod_id: '1'
Q: "If I put them under the same set_fact ansible gives an error that my_nodes_keys is not defined."
A: Unfortunately, it's not possible to 're-use' variables in set_fact. For example,
- set_fact:
var1: a
var2: "{{ var1 }}"
fails with the error:
The error was: 'var1' is undefined.
This means var2 is not able to use var1 declared in set_fact. There is an easy solution if you need var1 to declare var2 only. Put the declaration of var1 into task's vars. The task below works as expected
- set_fact:
var2: "{{ var1 }}"
vars:
var1: a
In your case, if you don't need the keys later in the playbook, put the declaration into task's vars
- set_fact:
my_nodes_dict: "{{ dict(my_nodes_keys|zip(my_nodes)) }}"
vars:
my_nodes_keys: "{{ my_nodes|map(attribute='node_name')|list }}"