In Ansible I've used register
to save the results of a task in the variable people
. Omitting the stuff I don't need, it has this structure:
{ "results": [ { "item": { "name": "Bob" }, "stdout": "male" }, { "item": { "name": "Thelma" }, "stdout": "female" } ] }
I'd like to use a subsequent set_fact
task to generate a new variable with a dictionary like this:
{ "Bob": "male", "Thelma": "female" }
I guess this might be possible but I'm going round in circles with no luck so far.
This module allows setting new variables. Variables are set on a host-by-host basis just like facts discovered by the setup module. These variables will be available to subsequent plays during an ansible-playbook run.
For Ansible, nearly every YAML file starts with a list. Each item in the list is a list of key/value pairs, commonly called a “hash” or a “dictionary”. So, we need to know how to write lists and dictionaries in YAML. There's another small quirk to YAML.
Note. This lookup plugin is part of ansible-core and included in all Ansible installations. In most cases, you can use the short plugin name dict even without specifying the collections: keyword.
Ansible registers are used when you want to capture the output of a task to a variable. You can then use the value of these registers for different scenarios like a conditional statement, logging etc. The variables will contain the value returned by the task. The common return values are documented in Ansible docs.
I think I got there in the end.
The task is like this:
- name: Populate genders set_fact: genders: "{{ genders|default({}) | combine( {item.item.name: item.stdout} ) }}" with_items: "{{ people.results }}"
It loops through each of the dicts (item
) in the people.results
array, each time creating a new dict like {Bob: "male"}
, and combine()
s that new dict in the genders
array, which ends up like:
{ "Bob": "male", "Thelma": "female" }
It assumes the keys (the name
in this case) will be unique.
I then realised I actually wanted a list of dictionaries, as it seems much easier to loop through using with_items
:
- name: Populate genders set_fact: genders: "{{ genders|default([]) + [ {'name': item.item.name, 'gender': item.stdout} ] }}" with_items: "{{ people.results }}"
This keeps combining the existing list with a list containing a single dict. We end up with a genders
array like this:
[ {'name': 'Bob', 'gender': 'male'}, {'name': 'Thelma', 'gender': 'female'} ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With