conditionally running tasks

86 views
Skip to first unread message

Vince Skahan

unread,
Mar 23, 2015, 6:42:55 PM3/23/15
to ansible...@googlegroups.com
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 ?



Jonathan Davila

unread,
Mar 24, 2015, 9:46:27 AM3/24/15
to ansible...@googlegroups.com
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
---
- hosts: all
  gather_facts
: yes
  tasks
:

   
- include: "{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml"

   
- name: set up serial console
      replace
:
         dest
:    /etc/
inittab
         regexp
:  "{{ serial_regex }}"
         replace
: "{{ serial_replace"

      notify
:
         
- telinit_q
  handlers
:
   
- name: telinit_q
     command
: "/sbin/telinit q"

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?

Vince Skahan

unread,
Mar 24, 2015, 2:19:31 PM3/24/15
to ansible...@googlegroups.com
On Tuesday, March 24, 2015 at 6:46:27 AM UTC-7, Jonathan Davila wrote:
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 (???)

 

Dag Wieers

unread,
Mar 24, 2015, 3:18:29 PM3/24/15
to ansible...@googlegroups.com
On Tue, 24 Mar 2015, Vince Skahan wrote:

> On Tuesday, March 24, 2015 at 6:46:27 AM UTC-7, Jonathan Davila wrote:
>
>> 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...

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

tasks:
- action: group_by key={{ ansible_distribution }}-{{ ansible_distribution_major }}

and have a a group_vars file for each group:

group_vars/debian-7
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.

--
Dag

Vince Skahan

unread,
Mar 24, 2015, 4:11:35 PM3/24/15
to ansible...@googlegroups.com
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.


 

Dan Vaida

unread,
Mar 28, 2015, 1:04:21 PM3/28/15
to ansible...@googlegroups.com
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.


Cheers,

Dan.
Reply all
Reply to author
Forward
0 new messages