One of the key features of Ansible is the use of handlers, which are tasks that are executed only when notified by other tasks. However, sometimes we need these handlers to always run, regardless of whether they were notified. In this post, we’ll see how to achieve this using a real example with Nginx.
What is a Handler in Ansible?
A handler in Ansible is a special task that runs when notified by other tasks. Handlers are useful for performing actions that should occur after one or more tasks have made changes to the system, such as restarting a service after updating its configuration.
Forcing Handlers to Run
Normally, handlers only run if they are notified by a task. But what if we want to ensure a handler always runs? For this, we can use the meta: flush_handlers
directive in our playbook.
Real Example: Restarting Nginx
Suppose we want to ensure that Nginx is restarted whenever we make changes to its configuration. Here’s an example of how to structure a playbook to achieve this.
Example Playbook
---
- name: Ensure Nginx is always restarted
hosts: all
become: yes
tasks:
- name: Install Nginx
apt:
name: nginx
state: present
notify: restart nginx
- name: Create a simple index.html
copy:
content: "<html><body><h1>Hello, world!</h1></body></html>"
dest: /var/www/html/index.html
notify: restart nginx
- name: Force handlers to run
meta: flush_handlers
- name: Always restart Nginx
service:
name: nginx
state: restarted
- name: Another task to show it continues
debug:
msg: "Nginx has been restarted, continuing with the playbook."
handlers:
- name: restart nginx
service:
name: nginx
state: restarted
Explanation
- Install Nginx: This task installs Nginx and notifies the handler to restart Nginx.
- Create a Simple index.html: This task creates or updates the
/var/www/html/index.html
file with simple HTML content and notifies the handler to restart Nginx. - Force Handlers to Run: This task ensures that any notified handlers up to this point are executed immediately.
- Always Restart Nginx: This task ensures that Nginx is restarted regardless of whether it was notified or not.
- Another Task: This is an example of a task that will run after the handlers have been flushed.
Conclusion
With this configuration, we ensure that Nginx is always restarted whenever the playbook is run, ensuring that any changes to the configuration are properly applied. Using meta: flush_handlers
and adding specific tasks to force handler execution gives us finer control over the behavior of our Ansible playbooks.