In your playbook example, the handler notification isn't triggering because of a fundamental Ansible behavior principle. Handlers only execute when the notifying task reports a changed
status. Your playbook output shows changed=0
, indicating the packages were already installed.
- hosts: HA
become: yes
gather_facts: false
tasks:
- name: Ensure Pacemaker packages are installed
yum:
name:
- pacemaker
- pcs
- resource-agents
state: latest
notify: start pcsd service
The key indicators in your output reveal the issue:
ok: [test-ha1]
- Task succeeded but didn't change anythingchanged=0
- No modifications were made to the system
Here are three approaches to ensure your handler executes:
# Solution 1: Force handler execution
- name: Force pcsd service start
systemd:
name: pcsd
state: started
when: "'HA' in group_names"
Or modify your original task to ensure changes:
# Solution 2: Add creates condition
- name: Install Pacemaker packages
yum:
name:
- pacemaker
- pcs
- resource-agents
state: latest
args:
creates: /usr/sbin/pcs
notify: start pcsd service
For more complex scenarios, consider these patterns:
# Multiple notifications example
- name: Configure cluster
template:
src: cluster.conf.j2
dest: /etc/cluster/cluster.conf
notify:
- restart pcsd
- reload corosync
handlers:
- name: restart pcsd
systemd:
name: pcsd
state: restarted
- name: reload corosync
systemd:
name: corosync
state: reloaded
Add these tasks to your playbook for better visibility:
- name: Debug handler notifications
debug:
msg: "Pending handlers: {{ ansible_run_tags }}"
- name: Show changed status
debug:
var: ansible_facts.changed
When your Ansible playbook shows "changed=0" in the play recap, this is the first clue why handlers aren't triggering. Handlers only run when a task reports a changed state. Your current output shows all tasks returned "ok" without changes.
# Check if packages are already installed
- name: Verify package states
command: rpm -q pacemaker pcs resource-agents
register: pkg_state
changed_when: false
# Force handler execution for testing
- name: Force package installation
yum:
name: "{{ item }}"
state: latest
loop:
- pacemaker
- pcs
- resource-agents
notify: pcsd start
when: "'not installed' in pkg_state.stdout"
The handler subsystem has several important behaviors:
- Notifications are queued but not immediately executed
- Identically named handlers only run once per play
- Handlers run after all normal tasks complete
For more control over handler execution:
# Explicit handler triggering
- meta: flush_handlers
# Conditional notifications
- name: Configure cluster
template:
src: cluster.conf.j2
dest: /etc/cluster/cluster.conf
notify:
- restart pcsd
- reload corosync
# Using listen with handlers
handlers:
- name: restart services
systemd:
name: "{{ item }}"
state: restarted
listen: "cluster services restart"
Here's a robust implementation pattern:
- hosts: HA
gather_facts: yes # Required for package module idempotency
vars:
cluster_packages:
- pacemaker
- pcs
- resource-agents
tasks:
- name: Install cluster packages
package:
name: "{{ cluster_packages }}"
state: latest
notify: ensure pcsd running
handlers:
- name: ensure pcsd running
systemd:
name: pcsd
state: started
enabled: yes
when: ansible_facts.pkg_mgr == "yum"