AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible Handlers Explained: How to Use and Flush Handlers

By Luca Berton · Published 2024-01-01 · Category: troubleshooting

How to flush the execution of an Ansible handler after the notification task using the ansible.builtin.meta module.

Ansible Handlers Explained: How to Use and Flush Handlers

When do Ansible Handlers run?

> By default, handlers run after all the tasks in a particular play have been completed.

See also: Ansible Multiple Handlers: Run Handlers in Sequence (listen, notify)

Links

• https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html#controlling-when-handlers-run

Demo

Let's jump into a real-life example of how to run an Ansible Handler immediately. First of all, we need a task changed status. The simplest Ansible module returning a "changed" status is Ansible command module with a Linux command, like "uptime". Let's suppose we would like to execute a handler immediately after the changed status and not wait for the next task using the ansible.builtin.meta module.

Initial Playbook

• flush_before.yml
---
- name: handler Playbook
  hosts: all
  tasks:
    - name: changed status
      ansible.builtin.command: "uptime"
      notify: message 1

- name: message 2 ansible.builtin.debug: msg: message 2

handlers: - name: message 1 ansible.builtin.debug: msg: message 1

inventory

localhost ansible_connection=local

Initial Execution

As you can notice the message 1 handler is executed AFTER the last task (message 2) of the Play being executed.

$ ansible-playbook -i inventory flush_before.yml

PLAY [handler Playbook] *********************************************************************

TASK [Gathering Facts] ****************************************************************** ok: [localhost]

TASK [changed status] ******************************************************************* changed: [localhost]

TASK [message 2] ************************************************************************ ok: [localhost] => { "msg": "message 2" }

RUNNING HANDLER [message 1] ************************************************************* ok: [localhost] => { "msg": "message 1" }

PLAY RECAP ****************************************************************************** localhost : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Modified Playbook

Let's add the ansible.builtin.meta Ansible module after the first task.

---
- name: handler Playbook
  hosts: all
  tasks:
    - name: changed status
      ansible.builtin.command: "uptime"
      notify: message 1

- name: flush ansible.builtin.meta: flush_handlers

- name: message 2 ansible.builtin.debug: msg: message 2

handlers: - name: message 1 ansible.builtin.debug: msg: message 1

Modified Execution

As you can notice the message 1 handler is executed BEFORE the last task (message 2) of the Play being executed.

% ansible-playbook -i inventory flush.yml

PLAY [handler Playbook] *********************************************************************

TASK [Gathering Facts] ****************************************************************** ok: [localhost]

TASK [changed status] ******************************************************************* changed: [localhost]

TASK [flush] ****************************************************************************

RUNNING HANDLER [message 1] ************************************************************* ok: [localhost] => { "msg": "message 1" }

TASK [message 2] ************************************************************************ ok: [localhost] => { "msg": "message 2" }

PLAY RECAP ****************************************************************************** localhost : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Conclusion

Now you know how to run immediately an Ansible Handler in a Playbook.

See also: Ansible ansible.builtin vs ansible.legacy: Collection Namespaces Explained

Related Articles

the Ansible inventory deep-divelisten-based handlers in Ansible

When to Flush Handlers

- name: Deploy and configure application
  hosts: all
  become: true
  tasks:
    - name: Deploy new config
      ansible.builtin.template:
        src: app.conf.j2
        dest: /etc/myapp/app.conf
      notify: restart myapp

# Flush handlers NOW — before the next task needs the service running - name: Force handler execution ansible.builtin.meta: flush_handlers

- name: Verify service is running ansible.builtin.uri: url: http://localhost:8080/health status_code: 200 retries: 5 delay: 3

handlers: - name: restart myapp ansible.builtin.service: name: myapp state: restarted

See also: Ansible troubleshooting - VMware Unknown error while connecting to vCenter or ESXi

Handler Patterns

  handlers:
    # Chain handlers with listen
    - name: restart web stack
      ansible.builtin.debug:
        msg: "Restarting web stack"
      listen: "web config changed"

- name: restart nginx ansible.builtin.service: name: nginx state: restarted listen: "web config changed"

- name: restart php-fpm ansible.builtin.service: name: php-fpm state: restarted listen: "web config changed"

FAQ

When should I use meta: flush_handlers?

Use it when a subsequent task depends on the handler having already run — for example, restarting a service before testing it, or reloading configuration before deploying dependent services.

Do handlers run if the play fails?

By default, no. Use --force-handlers or set force_handlers: true in ansible.cfg to run notified handlers even when the play fails.

Can a handler notify another handler?

Yes, starting from Ansible 2.2. Handlers can notify other handlers, creating a chain of actions.

Category: troubleshooting

Watch the video: Ansible Handlers Explained: How to Use and Flush Handlers — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home