using loop with a 'when'

66 views
Skip to first unread message

hbdhd...@gmail.com

unread,
Jun 8, 2018, 5:05:28 AM6/8/18
to Ansible Project
I would like for 'when' to take the item to evaluate from the loop. How do i do it? Is it even possible?

---
 hosts: servers
 vars:
   - a: True
   - b: False
   - c: True

 tasks:
   - name: ping it
     ping:
     when: letter == True
     loop:
       - { letter: 'a' }
       - { letter: 'b' }
       - { letter: 'c' }


Right now it fails with:
fatal: [127.0.0.1]: FAILED! => {"msg": "The conditional check 'letter == True' failed. The error was: error while evaluating conditional (letter == True): 'letter' is undefined

When I enclose letter in quotes and/or curly brackets, i get syntax error. 

This is just an extremely simplified version of what i actually need to do, so please concentrate on the actual question, not that the loop is done in too complex a way or that the test could be done differently (in the final version i'll probably have values other than true/false and each loop line will have multiple key-value pairs.)





Brian Coca

unread,
Jun 8, 2018, 9:36:10 AM6/8/18
to Ansible Project
You have 'item' as the representation of the 'current item in the
loop', but you are doing an indirection by 'letter' being the name of
a variable, the 'vars' lookup can resolve that, so you end up with:


when: lookup('vars', item['letter']) == True



--
----------
Brian Coca

hbdhd...@gmail.com

unread,
Jun 12, 2018, 11:45:13 AM6/12/18
to Ansible Project
It's ugly but worked like a charm. Thank you very much. 

Kai Stian Olstad

unread,
Jun 12, 2018, 12:07:59 PM6/12/18
to ansible...@googlegroups.com
On 12.06.2018 17:45, hbdhd...@gmail.com wrote:
> It's ugly but worked like a charm. Thank you very much.

You could use this if that look better

when: vars[item.letter] == True

And since the value is True or False you could also just do this

when: vars[item.letter]


--
Kai Stian Olstad

hbdhd...@gmail.com

unread,
Jun 12, 2018, 2:12:42 PM6/12/18
to Ansible Project
 

You could use this if that look better

   when: vars[item.letter] == True


Thank you for that. Now it's working AND it's pretty. Where is this documented? The lookup is "kind of" documented, though not anywhere near 'loop'. So it would never have occurred to me to connect the two. 


 
And since the value is True or False you could also just do this

   when: vars[item.letter]

As I said originally, this was just an oversimplified example. The real playbook has more values than just boolean true/false.  

Kai Stian Olstad

unread,
Jun 22, 2018, 8:57:13 AM6/22/18
to ansible...@googlegroups.com
On 12.06.2018 20:12, hbdhd...@gmail.com wrote:
>> You could use this if that look better
>>
>> when: vars[item.letter] == True
>>
>>
> Thank you for that. Now it's working AND it's pretty. Where is this
> documented? The lookup is "kind of" documented, though not anywhere
> near
> 'loop'. So it would never have occurred to me to connect the two.

vars is only documented one place, in the FAQ
https://docs.ansible.com/ansible/latest/reference_appendices/faq.html#when-should-i-use-also-how-to-interpolate-variables-or-dynamic-variable-names

"if you need to use a dynamic variable use the hostvars or vars
dictionary as appropriate"

vars is the same as hostvars[inventory_hostname]

--
Kai Stian Olstad

Brian Coca

unread,
Jun 22, 2018, 10:12:37 AM6/22/18
to Ansible Project
No, don't use vars[varname], it is NOT the same as hostvars[], it
includes vars not present in hostvars and it does not template the
variables in the same way. It is undocumented for a reason, it is not
meant for users, it was used internally (not anymore) and it is
scheduled for removal.

You CAN use the 'vars' lookup, i. e lookup('vars', 'varname') to deal
with dynamic variables, this also includes non host specific variables
not present in hostvars[]


----------
Brian Coca
Reply all
Reply to author
Forward
0 new messages