My pull request for with_nested
(
https://github.com/ansible/ansible/pull/7278) allows for all kind
of nested loops, including the simpler case that is handled by the
'with_subelements' lookup.
In David's example, where the items in the first level of the loop
are actually dictionary keys, to loop over the locations for each
person, you would write:
with_nested:
- people
- people[item.0].locations
Now, for a comparison with the 'with_subelements' lookup, consider
the following dict:
users:
- name: alice
authorized_keys:
- /tmp/alice/onekey.pub
- /tmp/alice/twokey.pub
- name: bob
authorized_keys:
- /tmp/bob/id_rsa.pub
To construct a loop with "with_subelements" you would write:
with_subelements:
- users
- authorized_keys
To construct the same loop with my version of 'with_nested' you
would write:
with_nested:
- users
- item.0.authorized_keys
Of course, the power of my version of 'with_nested' is that it
allows you to make multiple-level nested loops that cannot be
constructed in another way. For example, it allows for the pattern:
Loop over the hosts in a specific group, for each host access a list
hostvar and run a task for each item in that list. The list hostvar
could be as much deep as you want. Just add the loop levels needed
to reach it.
So, let's say that you want to create a number of VMs that will be
the members of a 'guests' group. You would have to connect to your
virtualiazation server host, let's call it 'vmhost', and do what
ever it is needed to create the VMs. After they have been created,
you want to deploy the VMs with Ansible, but to be able to do that
you would have first to bootstrap authorized ssh keys for 'root'
user in order to pass them in the VM bootstrapping process. This is
exactly a task for 'with_nested'. First, you configure your
inventory, as needed: basically you create the 'guests' group and
hostvars files for each host in that group with a 'users' variable
like the above. Then you construct the loop: At first level, you
would loop over each host in the 'guests' group. At second level,
you would loop over each user in the 'users' variable. At third
level you would loop over each item in the 'authorized' list. Also
add a conditional for 'root' user and ...voila:
- hosts: vmhost
tasks:
- name: Create authorized_keys for bootstrapping vm guests
authorized_key: user="{{
item.1.name }}" key="{{
lookup('file', item.2) }}" path=/path/to/bootstrap/guests/{{ item.0
}}/root/.ssh/authorized_keys
with_nested:
- groups["guests"]
- hostvars[item.0].users
- item.1.authorized_keys
when:
item.1.name == "root"