In Ansible, how do I iterate over a list of key/value pairs?

Chris F picture Chris F · Oct 30, 2017 · Viewed 11.3k times · Source

Say I have a defaults/main.yml file that has

---
my_vars:
- var1: value1
- var2: value2

How can I write my task to output my variables?

- debug: msg="The value of {{item.key}} is {{ item.value }}"
  with_items:
  - "What to put here???"

Answer

tedder42 picture tedder42 · Oct 31, 2017

You appear to be asking X but stating Y in your example. What I mean is that a list of key/value pairs that can be iterated through would look like this:

my_vars:
- var1: value1
  var2: value2

Or even like this:

my_vars:
  var1: value1
  var2: value2

To deal with your list of dicts, here's an example. I've added a variable to show how the dict is 'clumped'.

---
- hosts: localhost
  connection: local
  vars:
    my_var:
    - var1: value1
      varX: valueY
    - var2: value2
  tasks:
  - debug: var=item
    with_items: "{{my_var}}"
  - debug: var=item.var1
    when: "'var1' in item"
    with_items: "{{my_var}}"

output:

TASK [debug] ***********************************************************************************************************
ok: [localhost] => (item={'varX': 'valueY', 'var1': 'value1'}) => {
    "item": {
        "var1": "value1",
        "varX": "valueY"
    }
}
ok: [localhost] => (item={'var2': 'value2'}) => {
    "item": {
        "var2": "value2"
    }
}

TASK [debug] ***********************************************************************************************************
ok: [localhost] => (item={'varX': 'valueY', 'var1': 'value1'}) => {
    "item": {
        "var1": "value1",
        "varX": "valueY"
    },
    "item.var1": "value1"
}
skipping: [localhost] => (item={'var2': 'value2'})

Again, you can see the 'clumping', var1 and varX show in the same iteration. Ansible doesn't deal with deep nesting well. A case where Ansible can handle lists of dicts is when they are referring to similar things:

my_vars:
- name: bob
  legs: 4
  type: cow
- name: alice
  legs: 2
  type: bird

You can then iterate through that in two ways- either with_items or with_subelements.

If you truly have hetrogenous keys in lists and want to iterate through them one at a time, you would have to use nested includes (yuck). You can also build a filter. I've never done the former and have only done the latter once.