# complex when conditions

**URL:** <https://forum.ansible.com/t/complex-when-conditions/14696>\
**Category:** Ansible Project\
**Created:** [March 4, 2014, 12:11pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696 "2014-03-04T12:11:51Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Arie\_Skliarouk](https://avatars.discourse-cdn.com/v4/letter/a/edb3f5/32.png) [@Arie\_Skliarouk](https://forum.ansible.com/u/Arie_Skliarouk)\
**Post date:** [March 4, 2014, 12:11pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/1 "2014-03-04T12:11:51Z")

</div>

Hi,

I am migrating ansible from 0.9 to 1.5 and complex when condition don’t work anymore:

vars:  
not\_main: “‘$c\_main’ == ‘no’”  
is\_main: “‘$c\_main’ == ‘yes’”  
not\_lxc: “‘$lxc’ != ‘yes’”

tasks:

# This does not work properly, it is always being applied

- name: test0.conf  
action: template src=/tmp/test.conf.j2 dest=/tmp/test0.conf owner=ops group=ops mode=0444  
when: not\_main and not\_lxc

# This works but prints warnings about using ${foo} or $foo. This is what I used in the past with ansible 0.9 (with only\_if).

- name: test1.conf  
action: template src=/opt/opsfs/tmp/test.conf.j2 dest=/tmp/test1.conf owner=ops group=ops mode=0444  
when: $not\_main and $not\_lxc

# This works but is longer to type and not as readable as the first example

- name: test2.conf  
action: template src=/opt/opsfs/tmp/test.conf.j2 dest=/tmp/test2.conf owner=ops group=ops mode=0444  
when: c\_main == ‘no’ and lxc != ‘yes’

What is the correct way to use complex when conditions?

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [March 4, 2014, 12:49pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/2 "2014-03-04T12:49:44Z")

</div>

The following tricks are available:

---

<div class="post-metadata">

**Author:** ![Arie\_Skliarouk](https://avatars.discourse-cdn.com/v4/letter/a/edb3f5/32.png) [@Arie\_Skliarouk](https://forum.ansible.com/u/Arie_Skliarouk)\
**Post date:** [March 4, 2014, 1:28pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/3 "2014-03-04T13:28:44Z")

</div>

In my scripts I also use “or” expression… How would I do that? And what about the poor souls that want to use complex boolean expression?..

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [March 4, 2014, 1:34pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/4 "2014-03-04T13:34:15Z")

</div>

Complex conditionals and or statements are fine.

when: x \> 2 or y \>3

and complex conditionals are fine as well:

when: (x \> 2 or y \> 3) and (zebras == 4)

etc

---

<div class="post-metadata">

**Author:** ![Arie\_Skliarouk](https://avatars.discourse-cdn.com/v4/letter/a/edb3f5/32.png) [@Arie\_Skliarouk](https://forum.ansible.com/u/Arie_Skliarouk)\
**Post date:** [March 4, 2014, 1:41pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/5 "2014-03-04T13:41:35Z")

</div>

Will it be easier for ansible to recognize pre-defined condition if I put it in brackets?

vars:  
amazon: “yes”  
lxc: “no”  
is\_amazon: (amazon == “yes”)  
is\_lxc: (lxc == “yes”)

tasks:

- shell: echo hi 1

when: is\_amazon or is\_lxc

It would be sad if there is no way to use short syntax like this…

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [March 4, 2014, 1:50pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/6 "2014-03-04T13:50:25Z")

</div>

You’ll have to be sad then, at least for now.

Too much fuzzy logic is involved for the system to know what is a condition and what is a string, so only bare words  
are evaluated as conditionals.

---

<div class="post-metadata">

**Author:** ![Arie\_Skliarouk](https://avatars.discourse-cdn.com/v4/letter/a/edb3f5/32.png) [@Arie\_Skliarouk](https://forum.ansible.com/u/Arie_Skliarouk)\
**Post date:** [March 4, 2014, 3:06pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/7 "2014-03-04T15:06:47Z")

</div>

The ansible documentation has this example:

> vars:  
> epic: true  
> Then a conditional execution might look like:  
> tasks:
> 
> - shell: echo “This certainly is epic!”  
> when: epic

Would it be possible for ansible to interpret conditionals in vars: section and assign proper true/false values to the variables? So that in example below is\_amazon is assigned true?  
amazon: “yes”  
is\_amazon: (amazon == “yes”)

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [March 4, 2014, 3:11pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/8 "2014-03-04T15:11:50Z")

</div>

Yes, it can go one level deep.

You can’t build conditional expressions out of conditional expressions, but variables will expand.

I’d suggest writing a test playbook and trying it out!

---

<div class="post-metadata">

**Author:** ![Arie\_Skliarouk](https://avatars.discourse-cdn.com/v4/letter/a/edb3f5/32.png) [@Arie\_Skliarouk](https://forum.ansible.com/u/Arie_Skliarouk)\
**Post date:** [March 4, 2014, 3:45pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/9 "2014-03-04T15:45:53Z")

</div>

I tested various combinations, and in no case the is\_var\_evaluatedX got assigned value True…

> vars:  
> amazon: “no”  
> is\_var\_evaluated1: (amazon == ‘no’)  
> is\_var\_evaluated2: amazon == ‘no’  
> is\_var\_evaluated3: $amazon == ‘no’  
> is\_var\_evaluated4: “‘$amazon’ == ‘no’”

I would like to file feature request on adding conditional expression evaluation in vars section… Is there ansible’s BTS?

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [March 4, 2014, 4:41pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/10 "2014-03-04T16:41:14Z")

</div>

“Is there ansible’s BTS?”

[github.com/ansible/ansible](http://github.com/ansible/ansible).

However, it’s _already_ true that conditionals in the vars section work.

You still have some legacy variables in the bottom half, which is why 3 and 4 don’t work.

amazon: “no”  
is\_var\_evaluated1: (amazon == ‘no’)  
is\_var\_evaluated2: amazon == ‘no’

The first two should be true, and I’ve confirmed that they work on my end at least.

Note that if you forget to quote the no, it will be stored as a False, and this is even cleaner.

when: amazon

---

<div class="post-metadata">

**Author:** ![Arie\_Skliarouk](https://avatars.discourse-cdn.com/v4/letter/a/edb3f5/32.png) [@Arie\_Skliarouk](https://forum.ansible.com/u/Arie_Skliarouk)\
**Post date:** [March 23, 2014, 11:42am UTC](https://forum.ansible.com/t/complex-when-conditions/14696/11 "2014-03-23T11:42:04Z")

</div>

The following playbook does not work properly - the action is always executed, why is that?

---

<div class="post-metadata">

**Author:** ![Tomasz\_Kontusz](https://avatars.discourse-cdn.com/v4/letter/t/bc79bd/32.png) [@Tomasz\_Kontusz](https://forum.ansible.com/u/Tomasz_Kontusz)\
**Post date:** [March 23, 2014, 1:05pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/12 "2014-03-23T13:05:17Z")

</div>

> The following playbook does not work properly - the action is always  
> executed, why is that?
> 
> ---  
> - hosts: \*  
> &nbsp;&nbsp;&nbsp;vars:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x: 5  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y: 7  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;is\_false1: x\>y  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;is\_false2: x\>y

Here you set is\_false1 and is\_false2 to strings "x\>y", not to a result of evaluating it (and it would be the same if you put {{ }} around it)

> &nbsp;&nbsp;&nbsp;tasks:
> 
> &nbsp;&nbsp;&nbsp;- name: either is true  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shell: echo either is true  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when: is\_false1 or is\_false2

And here you check if either is\_false1 or is\_false2 is true-like - which they both are, as they are non-empty strings. What would work is putting them in {{ }} like this:

&nbsp;&nbsp;&nbsp;when: '{{ is\_false1 }} or {{ is\_false2 }}'

which looks bad, and tells you about {{ }} not being needed (which is not true in this case...).

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [March 23, 2014, 2:05pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/13 "2014-03-23T14:05:00Z")

</div>

You can’t load a “saved” conditional that way (at least currently) as the conditional loader doesn’t do recursive lookups.

– Michael

---

<div class="post-metadata">

**Author:** ![Arie\_Skliarouk](https://avatars.discourse-cdn.com/v4/letter/a/edb3f5/32.png) [@Arie\_Skliarouk](https://forum.ansible.com/u/Arie_Skliarouk)\
**Post date:** [March 24, 2014, 8:56am UTC](https://forum.ansible.com/t/complex-when-conditions/14696/14 "2014-03-24T08:56:56Z")

</div>

What is the recommended way to use “saved” conditionals?

Something like this:

ansible\_hosts has this:  
machine1 amazon=yes

vars:  
is\_amazon: (amazon == “yes”)  
tasks:

shell: echo we are on amazon  
when: is\_amazon

Can ansible treat expressions in brackets in vars: section as “saved” conditional? E.g. evaluate it and store in the value boolean True or False? This way the conditional loader does not need to do any lookups, just evaluate the expression as is.

Another question I have - whether the values of variables should be quoted? Double or single quote? From my experience, the quotes in ansible are treated as part of the value.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [March 24, 2014, 12:13pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/15 "2014-03-24T12:13:07Z")

</div>

" when: is\_amazon"

This is fine.

“whether the values of variables should be quoted?”

Only if they are strings.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [March 24, 2014, 2:50pm UTC](https://forum.ansible.com/t/complex-when-conditions/14696/16 "2014-03-24T14:50:09Z")

</div>

“which looks bad, and tells you about {{ }} not being needed (which is not true in this case…).”

The real fix would be to evaluate things as far recursively as we can, IMHO.

So as long as we have a ticket for that (let’s be sure we have one) {{ foo }} will become uneeded and we don’t need to change the warning.
