Using dictionary keys as a list in with_items

Excerpts from Rik Theys's message of 2013-05-17 09:20:26 -0400:

Hi,

I'm creating a playbook in which I register a variable to hold the virt
info output:

   - name: build info on guests
     action: virt command=info
     register: vminfo

In a followup task I want to add running guests to a group:

   - name: add running guests to new group
     action: add_host hostname=${item} groupname=running_vms
     with_items: $vminfo
     only_if: "'${item.status}' == 'running'"

This fails because with_items expects a list and I'm providing a dictionary.

Is there a way to make with_items use the keys of the dictionary as list
items?

I know this works in normal jinja2 templates:

    '{{ item.keys() }}'

So that might work in Ansible 1.2 (devel from git).

If you need something more complicated, you could always write a filter
plugins, which I'm fairly sure works with the jinja-style substitutions.

Aside: if using 1.2 you should not be using only_if.

It’s a legacy syntax that requires a lot of confusing quoting, and uses the variable system that is unlike templates, where we are consolidating now.

The new way is just this, much simpler:

when: foo.status == ‘running’

Here’s and example using the Jinja2’s dictsort filter to turn a dictionary into a list of (key,value) pairs which you can than iterate over with with_items:

vars:
databases:
service:
user: service_app
pass: ‘secret’

website:
user: website_app
pass: ‘secret’

brand_demo1:
user: demo1_app
pass: ‘secret’

tasks:

  • name: setup database users
    postgresql_user: name={{ item.1.user }} password={{ item.1.pass }}
    sudo_user: postgres
    with_items: databases|dictsort

Hope this helps.

Kal

Thanks for the great tip!

with_items: “{{ databases.keys() }}”

also seems to work, but then you would have no access to the values :slight_smile:

It is possible to have access to the value. For you case you can use: {{ database[item] }}