The most detailed free FDE + DevOps library: 140+ lessons, 70+ labs and 80 long-form articles, in English and Turkish. Start learning →

DevOps Practitioner · Module 5: Ansible and configuration management

Roles, Templates and Handlers That Fire Once

Roles package configuration the way charts package manifests: reusable shape with per-target data. Templates render the differences, handlers react to change, and a handler that fires on every run is a bug, not diligence.

10 min reading

Objectives

  • Explain what a role packages: tasks, templates, defaults and handlers
  • Render per-target config from templates with group and host variables
  • Wire handlers so restarts happen only when config actually changes
  • Diagnose the needless-restart fault from handler wiring

Why this matters

Every deploy restarts the database, including deploys that changed nothing, because the restart task runs unconditionally. Connections drop on a schedule nobody chose, and the team calls it normal. It is not normal: restarts are reactions to change, and change did not happen. Handlers exist to express exactly this: notify on change, run once at the end, stay quiet otherwise. The L38 lab fixes this exact fault, and this lesson explains why the fix is shaped the way it is.

Concepts

A role bundles tasks (the steps), templates (config files with variables), defaults (low-priority values the caller overrides), and handlers (tasks that run only when notified). Templates render per target from the merged variables: group values first, host values over them, explicit extra variables last. The L39 lab renders for different targets from one role and reviews the differences before applying, the same render-first habit M11 taught for charts.

Handlers fire on notification and run once per play, even when notified many times. The wiring is notify on the task that changes the config file (and only when it reports changed), listen on the handler. The classic fault is notifying unconditionally or from a task that always reports changed (a shell command without a changed-when rule): the handler fires every run, the service restarts every run, and the symptom looks like flakiness instead of wiring. Diagnosis reads the task states: if the config task says changed with identical content, the changed detection is missing, not the handler.

Defaults versus variables is a precedence decision with consequences. Role defaults lose to almost everything, which makes them safe homes for sane starting points. Group variables override defaults per environment. Extra variables win over all, so they suit one-off overrides, never permanent config. Values that must never change per target belong in the role body, not in variables at all.

Worked example

A demo role manages a web config file with port and worker settings per target. First run renders and restarts (changed, handler fires once). Second run reports ok throughout and the handler stays silent. Then the fault is staged: a shell task without changed detection notifies every run, the service restarts every run, and the fix adds the changed rule so silence returns.

Common wrong move

Putting service restarts as regular tasks at the end of the role instead of handlers. Every run restarts everything whether config changed or not, and the team stops noticing restarts at all, including the ones that actually signaled change.

Quick check

An optional 4-question self-check. Answers never leave your device, are not stored, and never count toward any assessment.

Lesson feedback

No published feedback yet.

Log in and complete the lesson to leave feedback.

Exercise

Run a demo role twice against a learner-owned target: show changed with one handler fire on the first run, full ok with silence on the second.

Pass criteria

The record shows first-run changed output with the single handler fire and second-run all-ok output with no restart.

Sources

Log in to track progressFree account: stores only your lesson progress and quiz results.