Let's say you are using the vars plugin to create a nested list. In this example, the "food" key is an outer list that contains two inner lists, fruit and veggies. debug can be used to output the entire list.
---
- hosts: localhost
gather_facts: false
vars:
food:
- fruit:
- apple
- banana
- orange
- grapes
- veggies:
- onion
- pepper
- carrot
- celery
tasks:
- ansible.builtin.debug:
var: food
...
Which should return the following.
ok: [localhost] => {
"food": [
{
"fruit": [
"apple",
"banana",
"orange",
"grapes"
]
},
{
"veggies": [
"onion",
"pepper",
"carrot",
"celery"
]
}
]
}
You can loop through the outer list.
---
- hosts: localhost
gather_facts: false
vars:
food:
- fruit:
- apple
- banana
- orange
- grapes
- veggies:
- onion
- pepper
- carrot
- celery
tasks:
- name: loop through the food list
ansible.builtin.debug:
msg: "{{ item }}"
with_items: "{{ food }}"
...
Which should return the following.
ok: [localhost] => (item={u'fruit': [u'apple', u'banana', u'orange', u'grapes']}) => {
"msg": {
"fruit": [
"apple",
"banana",
"orange",
"grapes"
]
}
}
ok: [localhost] => (item={u'veggies': [u'onion', u'pepper', u'carrot', u'celery']}) => {
"msg": {
"veggies": [
"onion",
"pepper",
"carrot",
"celery"
]
}
}
You can use an index numbers to loop through the inner lists.
---
- hosts: localhost
gather_facts: false
vars:
food:
- fruit:
- apple
- banana
- orange
- grapes
- veggies:
- onion
- pepper
- carrot
- celery
tasks:
- name: loop through the fruit list
ansible.builtin.debug:
msg: "{{ item }}"
with_items: "{{ food[0].fruit }}"
- name: loop through the veggies
ansible.builtin.debug:
msg: "{{ item }}"
with_items: "{{ food[1].veggies }}"
...
Which should return the following.
TASK [loop through the fruit list]
ok: [localhost] => (item=apple) => {
"msg": "apple"
}
ok: [localhost] => (item=banana) => {
"msg": "banana"
}
ok: [localhost] => (item=orange) => {
"msg": "orange"
}
ok: [localhost] => (item=grapes) => {
"msg": "grapes"
}
TASK [loop through the veggies list]
ok: [localhost] => (item=onion) => {
"msg": "onion"
}
ok: [localhost] => (item=pepper) => {
"msg": "pepper"
}
ok: [localhost] => (item=carrot) => {
"msg": "carrot"
}
ok: [localhost] => (item=celery) => {
"msg": "celery"
}
Set Fact
One option is to use the set_fact module to create a new variable that contains the nested list. In this example, a variable named "fruit" is created that contains the nested "fruit" list.
---
- hosts: localhost
gather_facts: false
vars:
food:
- fruit:
- apple
- banana
- orange
- grapes
tasks:
- name: set_fact fruit
ansible.builtin.set_fact:
fruit: "{{ item.fruit }}"
with_items: "{{ food }}"
- name: loop through the 'fruit' list
ansible.builtin.debug:
var: item
with_items: "{{ fruit }}"
...
Which should produce the following.
ok: [localhost] => (item=apple) => {
"ansible_loop_var": "item",
"item": "apple"
}
ok: [localhost] => (item=banana) => {
"ansible_loop_var": "item",
"item": "banana"
}
ok: [localhost] => (item=orange) => {
"ansible_loop_var": "item",
"item": "orange"
}
ok: [localhost] => (item=grapes) => {
"ansible_loop_var": "item",
"item": "grapes"
}
Inner / Outer Playbooks
Another option is to create two playbooks to loop through the "food" and "fruit" keys. Let's say outer.yml contains the following. This playbook uses the include_tasks module and the loop parameter with the loop_control loop_var option so that each item of the "food" list uses "food_item" as it's identifier.
---
- hosts: localhost
gather_facts: false
vars:
food:
- fruit:
- apple
- banana
- orange
- grapes
tasks:
- include_tasks: inner.yml
loop: "{{ food }}"
loop_var: food_item
...
And inner.yml could have the following to loop through the items in the "fruit" key.
- debug:
var: item
loop: "{{ food_item.fruit }}"
Which should output the following.
ok: [localhost] => (item=apple) => {
"ansible_loop_var": "item",
"item": "apple"
}
ok: [localhost] => (item=banana) => {
"ansible_loop_var": "item",
"item": "banana"
}
ok: [localhost] => (item=orange) => {
"ansible_loop_var": "item",
"item": "orange"
}
ok: [localhost] => (item=grapes) => {
"ansible_loop_var": "item",
"item": "grapes"
}
Did you find this article helpful?
If so, consider buying me a coffee over at