How can I iterate over a dictionary in a task?

5,019 views
Skip to first unread message

ZillaYT

unread,
Feb 10, 2017, 4:22:28 PM2/10/17
to Ansible Project
Say I have the following dictionary?

war_files:
  server1
:
 
- file1.war
 
- file2.war
  server2
:
 
- file1.war
 
- file2.war
 
- file3.war


Now I want to iterate over this, say a get_url task:

- name: Get the files depending on server name
  get_url
: src=http://some_host/{{ what to put here so I get each file for the server }}
 
when: "{{item.key}} in ansible_hostname"
  with_dict
: "{{ war_files }}"


IOW, if role is running in server1, it'll download file1.war and file2.war; if running on server2, it downloads file1.war, fiel2.war, and file3.war. I know there's probably other ways to do this, but I want to be able to do iterate through all the dictionary values in a single task.

Kai Stian Olstad

unread,
Feb 10, 2017, 4:57:23 PM2/10/17
to ansible...@googlegroups.com
get_url: src=http://some_host/{{ item }}
with_items: "{{ war_files[ansible_hostname] }}"


--
Kai Stian Olstad

ZillaYT

unread,
Feb 10, 2017, 5:24:34 PM2/10/17
to Ansible Project, ansible-pr...@olstad.com
Let me as a different question. What If I want to show ALL the files in a debug task, like this

- debug: msg="Key = {{ item.key }} values = {{ item.value }}"
  with_dict
: "{{ war_files }}"

I want to see an output like this

"msg" : "Key = server1 value = file1.war"
"msg" : "Key = server1 value = file2.war"
"msg" : "Key = server2 value = file1.war"
"msg" : "Key = server2 value = file2.war"
"msg" : "Key = server2 value = file3.war"

IOW, I want to iterate over the keys, then the values in each key.

Kai Stian Olstad

unread,
Feb 11, 2017, 4:35:18 AM2/11/17
to ansible...@googlegroups.com
On 10. feb. 2017 23:24, ZillaYT wrote:
> Let me as a different question. What If I want to show ALL the files in a
> debug task, like this
>
> - debug: msg="Key = {{ item.key }} values = {{ item.value }}"
> with_dict: "{{ war_files }}"
>
> I want to see an output like this
>
> "msg" : "Key = server1 value = file1.war"
> "msg" : "Key = server1 value = file2.war"
> "msg" : "Key = server2 value = file1.war"
> "msg" : "Key = server2 value = file2.war"
> "msg" : "Key = server2 value = file3.war"
>
> IOW, I want to iterate over the keys, then the values in each key.

Your item.value is a list so to list them as you want you will need a
loop in a loop.
Check out loop_control
https://docs.ansible.com/ansible/playbooks_loops.html#loop-control

Or you can change you variable structure so you can do this in one loop.

--
Kai Stian Olstad

ZillaYT

unread,
Feb 14, 2017, 9:53:06 AM2/14/17
to Ansible Project, ansible-pr...@olstad.com
The loop_control documentation doesn't make really explain how I can use it in my case.

ZillaYT

unread,
Feb 14, 2017, 11:54:30 AM2/14/17
to Ansible Project
I posted the same question on Stackoverflow, and got the answer I was looking for. Ugly, but it works.

Kai Stian Olstad

unread,
Feb 14, 2017, 12:19:30 PM2/14/17
to ansible...@googlegroups.com
On 14. feb. 2017 17:54, ZillaYT wrote:
> I posted the same question on Stackoverflow, and got the answer I was
> looking for. Ugly, but it works.
> http://stackoverflow.com/questions/42167747/how-to-loop-over-this-dictionary-in-ansible

Or just use loop in a loop with loop control.

Task:
- include: loop.yml
with_dict: "{{ war_files }}"
loop_control:
loop_var: outer_item


And the loop.yml contain the following.

---
- debug: msg="My key in {{ outer_item.key }} and the value is {{ item }}"
with_items: "{{ outer_item.value }}"


--
Kai Stian Olstad

ZillaYT

unread,
Feb 14, 2017, 12:29:40 PM2/14/17
to Ansible Project, ansible-pr...@olstad.com
Thanks, I'll try this too.

Felix Fontein

unread,
Feb 14, 2017, 1:10:25 PM2/14/17
to ansible...@googlegroups.com
Hi,

I created a plugin for more complicated looping, which also covers your
problem. You can find the plugin here:
https://github.com/felixfontein/ansible-dependentloop
With it, your problem could be solved as follows:

- name: Get the files depending on server name
get_url: src=http://some_host/{{ item.1 }}
when: "{{ item.0 }} in ansible_hostname"
with_dependent:
- "war_files.keys()"
- "war_files[item.0]"

Cheers,
Felix
Reply all
Reply to author
Forward
0 new messages