# Migrating from 1.1 to 1.2, problems replacing "only\_if" with "when"

**URL:** <https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131>\
**Category:** Ansible Project\
**Tags:** ubuntu\
**Created:** [July 16, 2013, 8:30am UTC](https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131 "2013-07-16T08:30:54Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Antonio\_Messina](https://avatars.discourse-cdn.com/v4/letter/a/9de053/32.png) [@Antonio\_Messina](https://forum.ansible.com/u/Antonio_Messina)\
**Post date:** [July 16, 2013, 8:30am UTC](https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131/1 "2013-07-16T08:30:54Z")

</div>

Hi all,

I am starting to migrate my playbooks from Ansible 1.1 to Ansible 1.2  
and I am getting a few problems.  
To distinguish between CentOS and Ubuntu distributions, I used to set  
two variables, "is\_centos" and "is\_ubuntu" in the following way:

&nbsp;&nbsp;&nbsp;&nbsp;is\_ubuntu: "'${ansible\_distribution}' == 'Ubuntu'"  
&nbsp;&nbsp;&nbsp;&nbsp;is\_centos: "'${ansible\_distribution}' == 'CentOS'"

and then use the "only\_if" statement in my tasks, like:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- action: debug msg="This is a CentOS"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;only\_if: $is\_centos

&nbsp;&nbsp;&nbsp;&nbsp;- action: debug msg="This is an Ubuntu machine"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;only\_if: $is\_ubuntu

and this worked as expected. Now I would like to use "when" instead of  
"only\_if", which is deprecated, but when I try the following:

&nbsp;&nbsp;&nbsp;&nbsp;- action: debug msg="This is a CentOS"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when: is\_centos

&nbsp;&nbsp;&nbsp;&nbsp;- action: debug msg="This is an Ubuntu machine"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when: is\_ubuntu

it always execute both tasks.  
I've also tried to convert the "vars" section to a jinja2-like declaration:

&nbsp;&nbsp;&nbsp;&nbsp;is\_ubuntu: "{{ ansible\_distribution == 'Ubuntu' }}"  
&nbsp;&nbsp;&nbsp;&nbsp;is\_centos: "{{ ansible\_distribution == 'CentOS' }}"

but still it does not work as expected.

This is the playbook I'm testing (on a Ubuntu machine):

---

<div class="post-metadata">

**Author:** ![Antonio\_Messina](https://avatars.discourse-cdn.com/v4/letter/a/9de053/32.png) [@Antonio\_Messina](https://forum.ansible.com/u/Antonio_Messina)\
**Post date:** [July 16, 2013, 8:54am UTC](https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131/2 "2013-07-16T08:54:39Z")

</div>

I think the problem is related to the fact that the value of  
"is\_ubuntu" becomes a \*string\* instead of a boolean. If I use as a  
conditional the following statement:

&nbsp;&nbsp;&nbsp;&nbsp;when: is\_ubuntu == 'True'

it works. Also, if I set the variable explicitly as a YAML boolean:

&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;is\_ubuntu: true  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;is\_centos: false

it works, but I don't know how to set these variables with YAML  
booleans instead of strings using an expression...

Also this does not work:

&nbsp;&nbsp;&nbsp;&nbsp;- action: set\_fact is\_ubuntu={{ ansible\_distribution == 'Ubuntu' }}  
&nbsp;&nbsp;&nbsp;&nbsp;- action: set\_fact is\_centos={{ ansible\_distribution == 'CentOS' }}

because "is\_ubuntu" and "is\_centos" still are evaluated as strings.

.a.

---

<div class="post-metadata">

**Author:** ![Antonio\_Messina](https://avatars.discourse-cdn.com/v4/letter/a/9de053/32.png) [@Antonio\_Messina](https://forum.ansible.com/u/Antonio_Messina)\
**Post date:** [July 16, 2013, 9:38am UTC](https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131/3 "2013-07-16T09:38:38Z")

</div>

I don't know if this is related or not, but I've also found that "{{  
variable }}" is treated differently from "${variable}".

In one of my playbooks I have something like:

&nbsp;&nbsp;&nbsp;&nbsp;- include: common/tasks/iptables.yml trusted\_hosts=${groups.slurm\_clients}

the iptables.yml file contains:

- action: template dest={{ destfile }}  
src=common/templates/etc/iptables.d/rules.v4.j2 owner=root group=root  
mode=0644  
&nbsp;&nbsp;tags: iptables

and the template contains:

{% for host in trusted\_hosts|sort %}  
-A INPUT -s {{ host }} -j ACCEPT  
{% endfor %}

the resulting output is:

-A INPUT -s compute001 -j ACCEPT  
-A INPUT -s compute002 -j ACCEPT

but if I use {{groups.all}} instead of ${groups.all} the resulting output is:

-A INPUT -s [ -j ACCEPT  
-A INPUT -s ' -j ACCEPT  
-A INPUT -s c -j ACCEPT  
-A INPUT -s o -j ACCEPT  
-A INPUT -s m -j ACCEPT  
-A INPUT -s p -j ACCEPT  
-A INPUT -s u -j ACCEPT  
-A INPUT -s t -j ACCEPT  
-A INPUT -s e -j ACCEPT  
-A INPUT -s 0 -j ACCEPT  
-A INPUT -s 0 -j ACCEPT  
-A INPUT -s 2 -j ACCEPT  
-A INPUT -s ' -j ACCEPT  
-A INPUT -s , -j ACCEPT  
-A INPUT -s -j ACCEPT  
-A INPUT -s ' -j ACCEPT  
-A INPUT -s c -j ACCEPT  
-A INPUT -s o -j ACCEPT  
-A INPUT -s m -j ACCEPT  
-A INPUT -s p -j ACCEPT  
-A INPUT -s u -j ACCEPT  
-A INPUT -s t -j ACCEPT  
-A INPUT -s e -j ACCEPT  
-A INPUT -s 0 -j ACCEPT  
-A INPUT -s 0 -j ACCEPT  
-A INPUT -s 1 -j ACCEPT  
-A INPUT -s ' -j ACCEPT  
-A INPUT -s ] -j ACCEPT

exactly like the "trusted\_hosts" variable is treated as the string:  
"['compute001', 'compute002']" instead of a list of strings.

.a.

---

<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:** [July 16, 2013, 11:49am UTC](https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131/4 "2013-07-16T11:49:46Z")

</div>

There’s already a ticket on this, I’ll have to find it.

I strongly recommend looking into the “group\_by” module for mapping configurations based on OS’es though, as the output is much nicer to not see all the ‘skipped’ steps.

groups.all is a list, you should walk over it in a loop.

---

<div class="post-metadata">

**Author:** ![Antonio\_Messina1](https://avatars.discourse-cdn.com/v4/letter/a/5fc32e/32.png) [@Antonio\_Messina1](https://forum.ansible.com/u/Antonio_Messina1)\
**Post date:** [July 16, 2013, 3:35pm UTC](https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131/5 "2013-07-16T15:35:05Z")

</div>

> There’s already a ticket on this, I’ll have to find it.

Thank you!

> I strongly recommend looking into the “group\_by” module for mapping configurations based on OS’es though, as the output is much nicer to not see all the ‘skipped’ steps.

I see your point, but I don’t really care about the output, and I want to migrate the syntax without changing too much. If I would have to use “group\_by” for this kind of things I will have to re-structure all my playbooks ☹

> groups.all is a list, you should walk over it in a loop.

I am not sure I understand your answer. I _am_ looping, but inside a template. I want to pass a list of hosts to a template, so that it will produce a line for each item of the list, this is something I can’t do using “with\_items”.  
The problem is that when I use {{ groups.all }}, in the template I get a string instead of a list, so iterating over it means iterating over all the characters of the string representation of the list…

.a.

---

<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:** [July 16, 2013, 5:27pm UTC](https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131/6 "2013-07-16T17:27:01Z")

</div>

{% for x in groups[‘all’] %}  
{{ x }}  
{% endfor %}

---

<div class="post-metadata">

**Author:** ![Antonio\_Messina](https://avatars.discourse-cdn.com/v4/letter/a/9de053/32.png) [@Antonio\_Messina](https://forum.ansible.com/u/Antonio_Messina)\
**Post date:** [July 16, 2013, 5:33pm UTC](https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131/7 "2013-07-16T17:33:37Z")

</div>

> {% for x in groups['all'] %}  
> &nbsp;&nbsp;&nbsp;{{ x }}  
> {% endfor %}

I don't want it hardcoded in the template!

As I wrote before, this is what I want to have:

&nbsp;&nbsp;&nbsp;&nbsp;- include: common/tasks/iptables.yml trusted\_hosts=${groups.slurm\_clients}

where "trusted\_hosts" might change (in this example is  
"slurm\_clients", but could be just a list of hosts).  
the iptables.yml file contains:

- action: template dest={{ destfile }}  
src=common/templates/etc/iptables.d/rules.v4.j2 owner=root group=root  
mode=0644  
&nbsp;&nbsp;tags: iptables

and the template contains:

{% for host in trusted\_hosts|sort %}  
-A INPUT -s {{ host }} -j ACCEPT  
{% endfor %}

If I write "trusted\_hosts={{groups.slurm\_clients}}" the template will  
receive a \*string\*, while if I write  
"trusted\_hosts=${groups.slurm\_clients}" it receives a list, as  
expected. Is this a bug or is the expected behavior? Is there a  
difference between "${variable}" and "{{variable}}" or there should  
not?

.a.

---

<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:** [July 16, 2013, 5:45pm UTC](https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131/8 "2013-07-16T17:45:23Z")

</div>

So we were intending to deprecate ${foo} but effectively it still works nicely for pass by reference, so I suspect it will be repurposed for such. In your case, it’s a matter of passing it in a dictionary rather than a string, since it can’t tell what you want the way it’s dereferenced above.

However this works today:

- include: common/tasks/main/iptables.yml  
vars:  
trusted\_hosts: ${groups.all}

Though I really want to unify this syntax so it plays more nicely with roles, also, i.e.

- include: …  
trusted\_hosts: ${groups.all}

Aka shorthand

- { include: filename.yml, trusted\_hosts: ${groups.all} }

The two latter forms are not implemented, but the first works for me today.

Hope this helps!

---

<div class="post-metadata">

**Author:** ![Antonio\_Messina](https://avatars.discourse-cdn.com/v4/letter/a/9de053/32.png) [@Antonio\_Messina](https://forum.ansible.com/u/Antonio_Messina)\
**Post date:** [July 17, 2013, 9:14am UTC](https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131/9 "2013-07-17T09:14:58Z")

</div>

Thank you, this clarifies it. I think that for now I will continue to  
use '${}' then, since it's not going to be deprecated.

.a.

---

<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:** [July 17, 2013, 11:19am UTC](https://forum.ansible.com/t/migrating-from-1-1-to-1-2-problems-replacing-only-if-with-when/13131/10 "2013-07-17T11:19:51Z")

</div>

It may be at some point, but in the case of passing a variable reference, it’s currently useful.
