Exercise 3: Fixing a shell Task That Always Reports Changed — Possible Solution ==================================================================== -- The problem -- -- -- shell: "systemctl restart myapp" with no changed_when or creates -- argument is exactly the non-idempotent trap the chapter describes. -- Every time this playbook runs, this task unconditionally restarts -- myapp and Ansible reports it as "changed" -- even on a run where -- nothing about the application or its configuration actually needed -- restarting. This has two real consequences: the PLAY RECAP becomes -- misleading, always showing a change even when the system was -- already in the correct state, and myapp gets needlessly restarted -- (a real, disruptive action, briefly interrupting the service) on -- every single playbook run, not just when a genuine change actually -- requires it. -- The fix, in YAML -- - name: Restart myapp only if config changed shell: "systemctl restart myapp" when: config_changed | default(false) changed_when: config_changed | default(false) -- Explanation of the fix -- -- -- Framed in words first: the restart should genuinely only happen -- (and only be reported as changed) when something upstream in the -- playbook actually modified myapp's own configuration -- not -- unconditionally on every run. The when: clause here uses a -- variable (config_changed) that a PRIOR task -- typically a template -- or copy task modifying myapp's config file -- would have set via -- register, reflecting whether that earlier task actually made a -- change. changed_when: config_changed | default(false) then -- explicitly tells Ansible to only mark THIS task as changed when -- that same condition is true, rather than trusting shell's own -- default (which is always "changed," regardless of what actually -- happened). Together, these two lines turn an always-changed, -- always-restarting task into one that behaves the way the chapter's -- own idempotent modules do -- only acting, and only reporting a -- change, when a change was genuinely needed. WHY THIS WORKS AS AN ANSWER ------------------------------ This identifies both concrete problems the always-changed behavior causes (a misleading recap and an unnecessary real restart), then provides a working YAML fix using the exact when:/changed_when: mechanism the chapter names, tied to a plausible upstream config-change signal rather than an arbitrary condition.