Stage 4 · Provision
Playbooks & Variables
Handlers & Notify
Restarting services only when configuration changes.
What Are Handlers?
Handlers are special tasks that only run when notified by another task. They execute at the end of a play, not immediately. Handlers are designed for actions that should only happen once even if multiple tasks trigger them — restarting a service, reloading a config, or flushing a cache.
---
- name: Configure web server
hosts: webservers
become: yes
tasks:
- name: Deploy nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart nginx
handlers:
- name: Restart nginx
service:
name: nginx
state: restartedThe handler runs only if the template task reports changed. If the config file is already correct, the handler does not run.
The Notify Mechanism
When a task reports changed, any task that notified it via notify is queued. All notified handlers run at the end of the play, in the order they are defined in the handlers section.
tasks:
- name: Deploy app config
template:
src: app.conf.j2
dest: /etc/app/config.yml
notify:
- Restart app
- Clear cache
- name: Deploy nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart nginx
handlers:
- name: Restart app
service:
name: app
state: restarted
- name: Clear cache
shell: rm -rf /var/cache/app/*
- name: Restart nginx
service:
name: nginx
state: restartedA task can notify multiple handlers. A handler can be notified by multiple tasks. Each handler runs only once per play.
Handlers do not run immediately when notified. They run after all tasks in the play complete. This ensures a service is restarted only once even if multiple config files change.
Handler Ordering
Handlers execute in the order they are defined in the handlers section, not in the order they were notified. Define handlers in the order they should execute.
# These run in definition order, not notification order
handlers:
- name: Clear cache # Runs first when notified
shell: rm -rf /var/cache/app/*
- name: Restart app # Runs second when notified
service:
name: app
state: restarted
- name: Restart nginx # Runs third when notified
service:
name: nginx
state: restartedIf the app needs the cache cleared before restarting, define the cache handler first. Execution order matters.
Flushing Handlers
Use meta: flush_handlers to force handler execution at any point during a play, rather than waiting until the end.
tasks:
- name: Deploy config
template:
src: app.conf.j2
dest: /etc/app/config.yml
notify: Restart app
- name: Flush handlers now
meta: flush_handlers
- name: Verify app is running
uri:
url: http://localhost:8080/health
status_code: 200Flushing ensures the app is restarted before the verification task runs. Without flush, the verify task would run against the old config.
Common Handler Patterns
handlers:
- name: Reload nginx
service:
name: nginx
state: reloaded
- name: Restart with timeout
service:
name: app
state: restarted
async: 60
poll: 10
- name: Run custom script
command: /opt/scripts/restart-app.sh
listen: "restart application"The listen keyword lets handlers respond to string-based notifications, which is useful for role-based handler patterns.
Use handlers for anything that should run only when configuration changes. This includes service restarts, config reloads, cache flushes, and system updates.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.