Question:
Say I have this dictionary
1 2 3 4 5 6 7 8 9 |
war_files: server1: - file1.war - file2.war server2: - file1.war - file2.war - file3.war |
and for now I just want to loop over each item (key), and then over each item in the key (value). I did this
1 2 3 4 |
- name: Loop over the dictionary debug: msg="Key={{ item.key }} value={{ item.value }}" with_dict: "{{ war_files }}" |
And I get this. It is of course correct, but is NOT what I want.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
ok: [localhost] => (item={'value': [u'file1.war', u'file2.war'], 'key': u'server1'}) => { "item": { "key": "server1", "value": [ "file1.war", "file2.war" ] }, "msg": "Server=server1, WAR=[u'file1.war', u'file2.war']" } ok: [localhost] => (item={'value': [u'file1.war', u'file2.war', u'file3.war'], 'key': u'server2'}) => { "item": { "key": "server2", "value": [ "file1.war", "file2.war", "file3.war" ] }, "msg": "Server=server2, WAR=[u'file1.war', u'file2.war', u'file3.war']" } |
I want to get an output that says
1 2 3 4 5 6 |
"msg": "Server=server1, WAR=file1.war" "msg": "Server=server1, WAR=file2.war" "msg": "Server=server2, WAR=file1.war" "msg": "Server=server2, WAR=file2.war" "msg": "Server=server2, WAR=file3.war" |
IOW, how can I write a task to iterates over the dictionary so it goes through each key, and then the items within each key? In essence, I have a nested array and want to iterate over it?
Answer:
Well, I couldn’t find a very easy way to do it, however, with a little bit of jinja2, we can achieve something of this sort:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/tmp ❯❯❯ cat example.yml --- - hosts: 127.0.0.1 vars: war_files: server1: - file1.war - file2.war server2: - file1.war - file2.war - file3.war tasks: - set_fact: war_files_list_of_dicts: | {% set res = [] -%} {% for key in war_files.keys() -%} {% for value in war_files[key] -%} {% set ignored = res.extend([{'Server': key, 'WAR':value}]) -%} {%- endfor %} {%- endfor %} {{ res }} - name: let's debug the crap out of this debug: var=war_files_list_of_dicts - name: Servers and their WARs!!! debug: msg: "Server={{ item.Server }}, WAR={{ item.WAR }}" with_items: "{{ war_files_list_of_dicts }}" |
And, when the playbook is run:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
/tmp ❯❯❯ ansible-playbook example.yml [WARNING]: provided hosts list is empty, only localhost is available PLAY [127.0.0.1] *************************************************************** TASK [setup] ******************************************************************* ok: [127.0.0.1] TASK [set_fact] **************************************************************** ok: [127.0.0.1] TASK [let's debug the crap out of this] **************************************** ok: [127.0.0.1] => { "war_files_list_of_dicts": [ { "Server": "server1", "WAR": "file1.war" }, { "Server": "server1", "WAR": "file2.war" }, { "Server": "server2", "WAR": "file1.war" }, { "Server": "server2", "WAR": "file2.war" }, { "Server": "server2", "WAR": "file3.war" } ] } TASK [Servers and their WARs!!!] *********************************************** ok: [127.0.0.1] => (item={'WAR': u'file1.war', 'Server': u'server1'}) => { "item": { "Server": "server1", "WAR": "file1.war" }, "msg": "Server=server1, WAR=file1.war" } ok: [127.0.0.1] => (item={'WAR': u'file2.war', 'Server': u'server1'}) => { "item": { "Server": "server1", "WAR": "file2.war" }, "msg": "Server=server1, WAR=file2.war" } ok: [127.0.0.1] => (item={'WAR': u'file1.war', 'Server': u'server2'}) => { "item": { "Server": "server2", "WAR": "file1.war" }, "msg": "Server=server2, WAR=file1.war" } ok: [127.0.0.1] => (item={'WAR': u'file2.war', 'Server': u'server2'}) => { "item": { "Server": "server2", "WAR": "file2.war" }, "msg": "Server=server2, WAR=file2.war" } ok: [127.0.0.1] => (item={'WAR': u'file3.war', 'Server': u'server2'}) => { "item": { "Server": "server2", "WAR": "file3.war" }, "msg": "Server=server2, WAR=file3.war" } PLAY RECAP ********************************************************************* 127.0.0.1 : ok=4 changed=0 unreachable=0 failed=0 |