Skip to content

Execute an additional custom Handler#

Problem#

How do I execute an additional Handler without having to edit a Role (especially for Galaxy Roles)?

Solution#

Create an additional Handler with a different name (or even without a name) and add it to your Playbook's Handlers block using listen.

To illustrate this, let's use the Role from Ansible Galaxy geerlingguy.nginx. We want to notify ourselves in a Slack channel if the play notifies restart nginx.

We take a look the available Handlers file in the Role:

geerlingguy.nginx/handlers/main.yml
- name: restart nginx
  ansible.builtin.service:
    name: nginx
    state: restarted

- name: validate nginx configuration
  ansible.builtin.command: nginx -t -c /etc/nginx/nginx.conf
  changed_when: false

- name: reload nginx
  ansible.builtin.service:
    name: nginx
    state: reloaded

And add listen to our Playbook accordingly using the name of the Handler. We could even add more Handlers to it as a list:

- hosts: all
  roles:
    - role: geerlingguy.nginx

  handlers:
    slack:
      channel: "#devops"
      msg: "Nginx was restarted/reloaded on {{ inventory_hostname }}"
      token: "{{ slack_token }}"
    delegate_to: localhost
    listen:
      - restart nginx
      - reload nginx

Explanation#

Both Handler names and listen can be called and enables flexible execution of actions decoupled from Handlers in Roles.

Observer Pattern

The listen pattern can also be understood as a simplified Observer Pattern Wikipedia.