Today I ran into an issue where I needed to use Ansible’s with_items
feature on the register
ed result of a previous task, one that also ran with_items
. To be more clear, here’s what my object looked like (in JSON for clarity):
{
"changed": false,
"msg": "All items completed",
"results": [
{
"machines": [
{
"ip": "127.0.0.1",
"name": "machine1"
},
{
"ip": "127.0.0.1",
"name": "machine2"
}
]
},
{
"machines": [
{
"ip": "127.0.0.1",
"name": "machine3"
},
{
"ip": "127.0.0.1",
"name": "machine4"
}
]
}
]
}
The problem is, I needed to use with_items
again, but for each machine this time, not each result.
##Solution I played with a few different ways of doing it, but settled on using Jinja2’s filters for the job:
"{{ my_with_items_registed_var.results|map(attribute='machines')|list }}"
To break it down, my variable is named my_with_items_registed_var
. This is the variable I registered previously through my first with_items
step. When using with_items
and register
, Ansible create an item in a results
array for each item that would have been registered in the normal case (where no with_items
is involed).
The filters come into play when we need to pull out specifically the machines
array. For this functionality, we use the map()
filter; specifying machines
as the attribute we want mapped.
Finally, we need to convert the generator back to a list with list
. I’m not 100% sure here, but it seems to flatten the machines arrays into one, as I was expected to need to do this after. If anyone know, please drop me a line @bbhoss.
##Conclusion This all seems fairly simple in conclusion, but I couldn’t easily find this information via searching, so hopefully this will be helpful to someone in the future.