Ansible Automation Ansible Handlers and Notifications 1 — Questions and Answers
Question 1: Where must Ansible handlers be defined within a playbook?
- In a 'handlers' section at the play level, separate from the 'tasks' section (Correct answer)
- Inside the 'tasks' section alongside regular tasks
- In a separate file always named handlers.yml
- At the top of the playbook before the 'hosts' key
Correct answer: In a 'handlers' section at the play level, separate from the 'tasks' section
Handlers are defined in a dedicated 'handlers' section at the play level, keeping them separate from regular tasks.
In an Ansible playbook, handlers are defined in a 'handlers' section that is a sibling of 'tasks' at the play level: - hosts: webservers tasks: - name: Copy config template: ... notify: Restart Apache handlers: - name: Restart Apache service: name: httpd state: restarted Handlers look identical to tasks but are only triggered by notifications. In roles, handlers are placed in the 'handlers/' directory.
Question 2: How many times will a handler execute if it is notified by 5 different tasks during a single play run?
- Once, at the end of the play (Correct answer)
- Five times, once per notification
- Zero times unless explicitly flushed
- Once per unique notifying task
Correct answer: Once, at the end of the play
Ansible deduplicates handler notifications—regardless of how many tasks notify the same handler, it runs only once at the end of the play.
Handlers in Ansible are deduplicated by design. Even if 10 tasks all notify 'Restart Nginx', the handler runs exactly once at the end of the play. This prevents cascading restarts when multiple configuration changes are applied. The handler executes in the order it is defined in the 'handlers' section, not in the order it was notified. This is one of the key benefits of the handler mechanism for managing service lifecycle.
Question 3: What is the 'meta: flush_handlers' task used for in an Ansible playbook?
- It forces all pending handlers to execute immediately at that point in the play rather than waiting until the end (Correct answer)
- It clears all queued handlers without executing them
- It resets handler notification status
- It exports handler definitions to a file
Correct answer: It forces all pending handlers to execute immediately at that point in the play rather than waiting until the end
'meta: flush_handlers' is a special task that immediately runs all pending handlers at that point in the play execution.
By default, handlers run at the end of a play. Sometimes you need handler execution to happen earlier—for example, restarting a service before running tasks that depend on it. 'meta: flush_handlers' triggers immediate execution of all pending notified handlers: - name: Deploy config template: ... notify: Restart App - meta: flush_handlers # Restart App runs here - name: Verify app is running uri: url: http://localhost:8080/health This is essential for multi-phase deployments.
Question 4: Can a handler notify another handler in Ansible?
- Yes, a handler can use 'notify' to trigger another handler (Correct answer)
- No, handlers cannot contain notify directives
- Yes, but only in Ansible 2.8 and later with listen topics
- No, circular dependencies would crash Ansible
Correct answer: Yes, a handler can use 'notify' to trigger another handler
Handlers can include 'notify' directives to chain handler execution, allowing one handler to trigger another.
Ansible supports handler chaining—a handler can itself contain a 'notify' directive to trigger another handler. This enables multi-step restart sequences: handlers: - name: Rebuild config command: /opt/app/rebuild-config.sh notify: Restart Application - name: Restart Application service: name: myapp state: restarted Chained handlers follow the same deduplication rules. This is useful for complex deployment patterns where a configuration rebuild must precede a service restart.
Question 5: What happens to pending handlers if a task fails during a play that has 'force_handlers: false' (the default)?
- Pending handlers are not executed—the play aborts and handlers are skipped (Correct answer)
- Pending handlers still execute before the play stops
- Pending handlers execute only on hosts that haven't failed
- Pending handlers are saved and run on the next playbook execution
Correct answer: Pending handlers are not executed—the play aborts and handlers are skipped
By default, if a play fails, pending handlers are not executed. Setting 'force_handlers: true' overrides this to ensure cleanup handlers always run.
When a task fails and 'force_handlers' is not set (default false), Ansible aborts the play for the failed host, and any pending handlers are skipped. This can be problematic for cleanup operations. Setting 'force_handlers: true' at the play level forces handler execution even if tasks fail: - hosts: all force_handlers: true tasks: ... handlers: ... This ensures cleanup, rollback, or notification handlers always execute regardless of task failures—similar to 'finally' blocks in programming languages.
Question 6: What is the 'listen' keyword used for in Ansible handlers?
- It allows multiple handlers to subscribe to a single notification topic, so all can be triggered with one 'notify' (Correct answer)
- It makes a handler listen on a network port for trigger events
- It enables handlers to respond to system log messages
- It creates a handler that polls for state changes
Correct answer: It allows multiple handlers to subscribe to a single notification topic, so all can be triggered with one 'notify'
The 'listen' keyword lets handlers subscribe to a named topic, allowing a single 'notify' to trigger multiple handlers.
The 'listen' keyword enables a pub/sub model for handlers. Multiple handlers can listen to the same topic, and a single notify call triggers all of them: handlers: - name: Restart Apache service: name=httpd state=restarted listen: web stack restarted - name: Restart PHP-FPM service: name=php-fpm state=restarted listen: web stack restarted tasks: - name: Deploy app template: ... notify: web stack restarted This decouples role internals from consumer names, making roles more composable.
Where must Ansible handlers be defined within a playbook?