Ansible iterate a dictionary with lists
Solution 1:
First off, you might want to consider using the file
module, rather than shell
. It's less failure prone, and ostensibly idempotent. However, that might give you some issues with mixing directories, files, and file globs. YMMV.
As for the heart of the question, I would set up your variables like so:
users:
- username: bar
directories:
- path: /data
permissions: rX
- path: /js
permissions: rX
- username: foo
directories:
- path: /
permissions: rwX
The play would then look like this:
- name: Change mod/own
shell: chown {{ item.0.username }} {{ item.1.path }};chmod u+{{ item.1.permissions }} {{ item.1.path }
with_subelements:
- users
- directories
Solution 2:
This is a good output example that you can try yourself.
Create a new playbook called iteration_loop.yml
:
---
- name: Change mod/own
hosts: all
tasks:
- name: show me the iterations
debug: msg={{ item.0.username }} {{ item.1.path }} then {{ item.1.permissions }} {{ item.1.path }}
with_subelements:
- users
- directories
vars:
users:
- username: bar
directories:
- path: /data
permissions: rX
- path: /js
permissions: rX
- username: foo
directories:
- path: /
permissions: rwX
Then run the playbook like this:
ansible-playbook -i '172.16.222.131,' iteration_loop.yml
and the output should give you how the items are accessed:
PLAY [Change mod/own] *********************************************************
GATHERING FACTS ***************************************************************
ok: [172.16.222.131]
TASK: [show me the iterations] ************************************************
ok: [172.16.222.131] => (item=({'username': 'bar'}, {'path': '/data', 'permissions': 'rX'})) => {
"item": [
{
"username": "bar"
},
{
"path": "/data",
"permissions": "rX"
}
],
"msg": "bar"
}
ok: [172.16.222.131] => (item=({'username': 'bar'}, {'path': '/js', 'permissions': 'rX'})) => {
"item": [
{
"username": "bar"
},
{
"path": "/js",
"permissions": "rX"
}
],
"msg": "bar"
}
ok: [172.16.222.131] => (item=({'username': 'foo'}, {'path': '/', 'permissions': 'rwX'})) => {
"item": [
{
"username": "foo"
},
{
"path": "/",
"permissions": "rwX"
}
],
"msg": "foo"
}
PLAY RECAP ********************************************************************
172.16.222.131 : ok=2 changed=0 unreachable=0 failed=0
Solution 3:
Assuming that dict={a:[1,2,3],b:[1,2]}
and so on:
- name: Flattened list
set_fact:
flattened: "{{ dict.values() | sum(start=[]) }}"
Now flattened == [1,2,3,1,2]