Troubleshooting Ansible Handler Notification Failure in Pacemaker Cluster Setup


3 views

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 anything
  • changed=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"