Accessing a list of dictionaries, within a list of dictionaries, using with_items

I asked in IRC about this, and was asked to post this here.

We use ansible to deploy multiple instances of our application. Our playbooks bring in application config data by including a var file that has a list of dictionaries containing instance specific data, like so:

app_settings.yml

applications:

etc etc

},

etc etc

},

Recently we needed to restrict access to certain environments, and are doing this using http basic auth. Ansible has an htpasswd tool! Excellent. Instead of having to manage the data manually, we can just store username/passwords along with our configuration file and let ansible take care of managing the hashing. The settings dictionary now looks like this:

app_settings.yml

applications:

  • { domain: site1.example.com,
    mysql_user: site1,
    http_auth_users:
  • {user: ‘user1’, pass: ‘user1’},
  • {user: ‘user2’, pass: ‘user2’},

etc etc

},

the question is, how can we access this data in a loop? many of our tasks use with_items: ${applications} and things like ${item.domain}, but here we need to do a double loop - once over the applications, and then an inner loop on the http_auth_users list, passing each dict in the list to the htpasswd module

I hear there is new support for this in the brand new subelement module?

Thanks as always for your help and hard work on ansible! We greatly appreciate it.

  • Robert Warner

Hi Robert,

Yep, this looks like with_subelements to me.

I recently added some docs on it:

http://ansibleworks.com/docs/playbooks_loops.html#looping-over-subelements

In the above, you’d be doing:

with_subelements:

  • applications
  • http_auth_users

And then each {{ item.0 }} would be the whole data item, and {{ item.1 }} would be each user in the http_auth_user list

For instance, the mysql_user would be {{ item.0.mysql_user }} and each http_auth user would be like so:

{{ item.1.user }}

Let me know if this works for you or if you have further questions.

Thanks!