Calling Ansible handlers based on OS distributions

Sometimes you’ve got an Ansible task that should notify another task after a change. In Ansible this is called a handler and a description can be found here. Mostly the handler can be defined OS-independent. In this blog post, we show you, how to use a list of handlers for different OS distributions.

Our solution is quite simple. In the task, we set a list of OS-dependent Ansible handlers. And in the handler-section, we set a when condition that triggers only for the defined OS distribution.

So in this example below we notify two Ansible handlers named redhat handler and debian handler, which will only trigger when their condition matches.

---
- hosts: all

  tasks:
  - name: create a hello world textfile
    copy:
      content: "Hello World!"
      dest: /tmp/hello.txt
      owner: root
      group: root
      mode: 0640
    notify:
      - redhat handler
      - debian handler
    sudo: yes

  handlers:
  - name: redhat handler
    debug: msg='redhat'
    when: ansible_distribution == "RedHat"
  
  - name: debian handler
    debug: msg='debian'
    when: ansible_distribution == "Debian"

If you run this playbook on a Debian system, you’ll see that both Ansible handlers will be notified. While the Debian handler is executed, the handler for Red Hat will be skipped, because the when condition doesn’t match (ansible_distribution == “RedHat”).

TASK: [create a hello world textfile] ****************************************

changed: [10.211.55.13] => {"changed": true, "checksum": "2ef7bde608ce5404e97d5f042f95f89f1c232871", "dest": "/tmp/hello.txt", "gid": 0, "group": "root", "md5sum": "ed076287532e86365e841e92bfc50d8c", "mode": "0640", "owner": "root", "size": 12, "src": "/home/ansible/.ansible/tmp/ansible-tmp-1442318701.24-147707146377642/source", "state": "file", "uid": 0}

NOTIFIED: [redhat handler] ****************************************************
skipping: [10.211.55.13]

NOTIFIED: [debian handler] ****************************************************
ok: [10.211.55.13] => {
    "msg": "debian"
}

PLAY RECAP ********************************************************************
10.211.55.13               : ok=3    changed=1    unreachable=0    failed=0

This solution can be useful for example to manage certificate authorities, where different commands should be executed after adding a new certificate. Debian => /usr/sbin/update-ca-certificates, RedHat => /bin/update-ca-trust.

Please feel free to leave a comment, if you’ve got another solution.

9 Comments

  • Tomáš Havlas

    Hi,
    I really like your idea, but I don’t like listing handlers for all the possible distributions in notify, so why don’t use a variable when calling a handler. Simply replacing handlers in your example with following “{{ ansible_os_family|lower }} handler”, should have the same outcome. I’d like to hear your opinion about this solution.

  • jatin

    Is it possible to put a condition in notify rather than in handler ? Like notify requires to call multiple handlers and each handler will be trigered on a condition check ?

  • Denis

    Thanks Man!

  • doula

    How do you in November?

  • life insurance

    Lent you have shared, good stuff.