# conditionally running tasks

**URL:** <https://forum.ansible.com/t/conditionally-running-tasks/17822>\
**Category:** Ansible Project\
**Created:** [March 23, 2015, 10:42pm UTC](https://forum.ansible.com/t/conditionally-running-tasks/17822 "2015-03-23T22:42:55Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Vince\_Skahan](https://avatars.discourse-cdn.com/v4/letter/v/5e9695/32.png) [@Vince\_Skahan](https://forum.ansible.com/u/Vince_Skahan)\
**Post date:** [March 23, 2015, 10:42pm UTC](https://forum.ansible.com/t/conditionally-running-tasks/17822/1 "2015-03-23T22:42:55Z")

</div>

What’s the preferred way to conditionally configure something if the ‘how’ changes from os to os, and version to version ‘of’ any particular os ?

Here’s an example - setting up a serial console on a SysVinit system (example - debian 7.8):

> * * *
> 
> - hosts: all
> 
> gather\_facts: yes
> 
> tasks:
> 
> - name: set up serial console
> 
> replace:
> 
> dest: /etc/inittab
> 
> regexp: “^#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100$”
> 
> replace: “T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100”
> 
> notify:
> 
> - telinit\_q
> 
> handlers:
> 
> - name: telinit\_q
> 
> command: “/sbin/telinit q”

But that only works on debian-7 systems. I can limit it to debian-7 by inserting

> 

when:  
ansible\_distribution == ‘Debian’ and ansible\_distribution\_version == ‘7’

> 

But that doesn’t handle centos-5 which has a slightly different search/replace needed…or centos-7 which uses systemd, and so on.

I guess I’m struggling with how to have a set (tree?) of plays for task-ABC that are known good, but only using them when the os/version say to do it that way.

Is the preferred way to include .yml files based on distribution/version values discovered at runtime ? Examples ?

---

<div class="post-metadata">

**Author:** ![Jonathan\_Davila](https://avatars.discourse-cdn.com/v4/letter/j/e0b2c6/32.png) [@Jonathan\_Davila](https://forum.ansible.com/u/Jonathan_Davila)\
**Post date:** [March 24, 2015, 1:46pm UTC](https://forum.ansible.com/t/conditionally-running-tasks/17822/2 "2015-03-24T13:46:27Z")

</div>

You could try to variablize the values of the module parameters into os-specific vars files and then do conditional include statements based on the os.

So like

`

---

<div class="post-metadata">

**Author:** ![Vince\_Skahan](https://avatars.discourse-cdn.com/v4/letter/v/5e9695/32.png) [@Vince\_Skahan](https://forum.ansible.com/u/Vince_Skahan)\
**Post date:** [March 24, 2015, 6:19pm UTC](https://forum.ansible.com/t/conditionally-running-tasks/17822/3 "2015-03-24T18:19:31Z")

</div>

> You could try to variablize the values of the module parameters into os-specific vars files and then do conditional include statements based on the os.  
> Where you would have files named like debian-7.yml, etc. And within those files you would have serial\_regex/replace defined along with any other vars.
> 
> Does that help?

Notionally yes, but ansible doesn’t seem to like variables in - include: statements.

Does ansible do ‘include’ before ‘gather\_facts’ perhaps ???  
If so, that would be a pretty major bug/misfeature to me…

Here’s an example that shows the problem.

> - hosts: all
> 
> gather\_facts: yes
> 
> tasks:
> 
> - debug: msg=“{{ ansible\_distribution }}-{{ ansible\_distribution\_version }}.yml”
> 
> - include: “{{ ansible\_distribution }}-{{ ansible\_distribution\_version }}.yml”

Running that trivial playbook fails:

> ERROR: file could not read: /tmp/{{ ansible\_distribution }}-{{ ansible\_distribution\_version }}.yml

But if you try to debug only (after commenting out the include: line) the fact collection works ok:

> PLAY [all] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
> 
> GATHERING FACTS \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
> ok: [192.168.0.169]
> 
> TASK: [debug msg=“{{ ansible\_distribution }}-{{ ansible\_distribution\_version }}.yml”] \*\*\*  
> ok: [192.168.0.169] =\> {  
> “msg”: “Debian-7.8.yml”  
> }
> 
> PLAY RECAP \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
> 192.168.0.169 : ok=2 changed=0 unreachable=0 failed=0

I tried similar things setting variables, custom facts, etc. to no avail. Seems like ansible includes first as it does its runs (???)

---

<div class="post-metadata">

**Author:** ![Dag\_Wieers](https://avatars.discourse-cdn.com/v4/letter/d/45deac/32.png) [@Dag\_Wieers](https://forum.ansible.com/u/Dag_Wieers)\
**Post date:** [March 24, 2015, 7:18pm UTC](https://forum.ansible.com/t/conditionally-running-tasks/17822/4 "2015-03-24T19:18:21Z")

</div>

I haven't tested your example, but what I usually do is something like:

&nbsp;&nbsp;&nbsp;tasks:  
&nbsp;&nbsp;&nbsp;- action: group\_by key={{ ansible\_distribution }}-{{ ansible\_distribution\_major }}

and have a a group\_vars file for each group:

&nbsp;&nbsp;&nbsp;group\_vars/debian-7  
&nbsp;&nbsp;&nbsp;group\_vars/redhat-6

This will automatically pull variables from the matching group\_vars file.

In fact, in large/complex environments my inventory script has this kind of functionality included so that it has all the needed variables and groups available for every playbook and play from the very start.

---

<div class="post-metadata">

**Author:** ![Vince\_Skahan](https://avatars.discourse-cdn.com/v4/letter/v/5e9695/32.png) [@Vince\_Skahan](https://forum.ansible.com/u/Vince_Skahan)\
**Post date:** [March 24, 2015, 8:11pm UTC](https://forum.ansible.com/t/conditionally-running-tasks/17822/5 "2015-03-24T20:11:35Z")

</div>

Thanks, that helps a lot, I think I’ll go that route…

If you have time, see if you can get variable substitution to work in an include statement. It sure ‘seems’ to try to include the file before doing things defined above it (like grabbing the facts) which to me is a design flaw. If we wanted to have calculated filenames based on other things defined above it in the sequence, how is that possible currently ? How do we know (or control) the ordering of what ansible is doing ?

Lots of cool stuff here, just a bit undefined and perhaps buggy from what I’ve seen thus far, but I might just not be looking up the right buzzwords in their docs.

---

<div class="post-metadata">

**Author:** ![vaida.dan](https://avatars.discourse-cdn.com/v4/letter/v/5daacb/32.png) [@vaida.dan](https://forum.ansible.com/u/vaida.dan)\
**Post date:** [March 28, 2015, 5:04pm UTC](https://forum.ansible.com/t/conditionally-running-tasks/17822/6 "2015-03-28T17:04:21Z")

</div>

Hi Vince,

Jonathan’s approach is also valid. Just replace “include” with “include\_vars” and it will work.

The group\_by approach is pretty neat as it doesn’t produce the pesky “skipping” entries in the run output.

A useful read on precedence: [http://docs.ansible.com/playbooks\_variables.html#variable-precedence-where-should-i-put-a-variable](http://docs.ansible.com/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable)

Cheers,

Dan.
