Proper use of "when" conditional

61 views
Skip to first unread message

ender

unread,
Sep 30, 2015, 1:25:48 PM9/30/15
to Ansible Project
I am fairly new to Ansible and having a problem with a playbook in which I wish to have a handler run one script if the target OS is in the RedHat family and another script if the target OS is in the Debian family.  I am clearly doing this wrong.  Here's the relevant snippet:

[...]
  handlers:
    - name: restart foo
      shell: /etc/init.d/barfoo stop ; /etc/init.d/barfoo start
      when: ansible_os_family == "RedHat"
      shell: /etc/init.d/bazfooinit stop ; /etc/init.dbazfooinit start
      when: ansible_os_family == "Debian"
[...]

This works fine for the targets running a Debian distro (in this case two Debians and an Ubuntu) but does not work. for the hosts running a Red Hat distro (actually three CentOS servers, all running the same version of CentOS).  The handler just returns "skipping: [<host>]" for each CentOS host.

Running ansible against those targets with -m setup -a 'filter=ansible_os_family' returns the expected "RedHat" for the CentOS hosts.

I suspect I am doing something wrong.  Is it not possible to have two "when:" statements and only the last one is interpreted?  That would seem to explain what I am seeing.  If that, or something similar is the case how can I accomplish what I need to do... kind of a "if RedHat, elseif Debian" sort of behavior?

Thanks!

David Karban

unread,
Sep 30, 2015, 2:59:33 PM9/30/15
to ansible...@googlegroups.com
HI Ender,

I believe there can be only one action in handler. Use variables to solve this. First task in role:
- name: Load the OS specific variables
  include_vars: "{{ ansible_os_family }}.yml"

in vars/ have a files:
RedHat.yml
service_name: "barfoo"

Debian.yml
service_name: "barfooinit"

Then in handler:
  handlers:
    service: name={{ service_name }} state=restarted

New platform means new variable file, no task modifications.

Regards
David Karban
Linux server specialist/Specialista na správu linuxových serverů
www.karban.eu

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/58f66483-d934-4ccb-8b76-a83d3c7c6fb8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

ender

unread,
Oct 1, 2015, 8:40:02 AM10/1/15
to Ansible Project
Thanks for the reply.  I think this will end up being more complicated as I cannot use the service module but must run the script with a stop argument and then a start argument.  Can I define a function in Ansible?  Have a RedHat.yml file that defines a "restart" function using the proper shell information (a task?) for that OS and a separate Debian.yml file with the correct syntax for that OS and then call the function "restart" in a handler?

David Karban

unread,
Oct 1, 2015, 10:51:42 AM10/1/15
to ansible...@googlegroups.com
Not a problem too, define two handlers:

- name: stop foo
  service: name={{ service_name }} state=stopped

- name: start foo
  service: name={{ service_name }} state=started

In tasks define:

tasks:
  - name: change happen here
    ...
    notify:
      - stop foo
      - start foo

This way, both handlers will be called (top to down, so stop first).  If you cannot use service module, just change handlers to shell as you have in your first mail.


David Karban
Linux server specialist/Specialista na správu linuxových serverů
www.karban.eu

Reply all
Reply to author
Forward
0 new messages