Proper use of "when" conditional

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: []” 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!

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.

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?

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