Ansible - select attributes that match

May 29, 2015   #ansible 

Sometimes it’s useful to be able to access specific content from a dict based on values, rather than keys.

Take for example, a user dict that contains the following information.

--- users: - name: john email: john@example.com - name: jane email: jane@example.com - name: fred email: fred@example.com password: 123!abc

You might want to send an email to john and jane, suggesting they set a password.

Now you could get the emails to use from a template lookup. Looping the items in the list, checking the password attribute, and building a list based on it. e.g.

# get_emails.j2 [ {% for user in users %} {% if user.password is undefined %} {{ user.email }}, {% endif %} {% endfor %} ]

which you might call using something like…

- set_fact: emails: "{{ lookup('template', './get_emails.j2' }}"

However that requires a jinja template file, and requires looking in two places to see the logic. If you don’t like that approach, you could use a filter

- set_fact: emails: "{{ users | selectattr('password', 'undefined') | map(attribute='email') | list }}"

which essentially says, select all list objects which have no password key, then from that selection get all email values, and return them in a list.

Note: the second attribute of selectattr must be a jinja2 builtin test