Skip to content

Handlers are not instance-aware; multiple role invocations in one play restart the wrong service or skip a reload #269

Description

@SrX

The role assumes a single PowerDNS Authoritative instance per host. When the role is invoked more than once in the same play (e.g. include_role in a loop, each pass setting a different pdns_service_name), the handlers in handlers/main.yml do not carry per-instance context and can restart the wrong instance or drop a needed restart.

Root cause is the combination of two Ansible facts:

  1. Handlers are global to the play and keyed by name / listen topic. The Restart PowerDNS handler listens on the single topic restart pdns. N notifications from N instances collapse to a single handler run.
  2. The service name is resolved at handler-execution (flush) time, not at notify time: the handler uses name: "{{ pdns_service_name }}". Because each instance passes pdns_service_name as an include-scoped variable, that scope is gone by the time handlers flush, so the templated name does not resolve to the instance that actually changed. The result is that a single restart fires against whatever pdns_service_name resolves to at flush time, and the other instances' restarts are silently skipped.

Relevant code (handlers/main.yml, master):

- name: Restart PowerDNS
  ansible.builtin.systemd:
    name: "{{ pdns_service_name }}"
    state: restarted
  listen: restart pdns
  ...

Repro sketch:
- One play, two include_role passes of this role, pdns_service_name: pdns@a and pdns_service_name: pdns@b.
- Change the generated config for both instances so both notify restart pdns.
- At end-of-play flush the handler runs once, restarting only one service name; the second instance is not restarted.
- A meta: flush_handlers between the two invocations is the current workaround and confirms the diagnosis.

Suggested direction (maintainers' call): make the handler topic/name instance-scoped so notifications do not dedup across instances -- e.g. derive the listen topic or handler name from the instance identity -- or document explicitly that the role is single-instance-per-play and that callers must flush_handlers between invocations.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions