AnsibleXLIV · Failure Modes and Partial Fleet FailureFailure Modes and Partial Fleet Failure
Retry, roll back, quarantine or investigate
What you'll learn
- Apply explicit criteria to choose between the four responses to a partial failure
- State the evidence each branch requires before it can be chosen
- Identify which decisions require an authority beyond the person running the play
- Write the decision criteria into a change plan before execution
Prerequisites
Verified against ansible-core 2.21.x · ansible (community package) 14.x · Python (controller) 3.12+ · ansible-lint 26.x · Molecule 26.x · Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL / Rocky / AlmaLinux 9.x · 2026-08-11
You have the four host lists. You know whether the 220 are consistent. You have audited the play for rerun safety. Now something has to happen, and there are exactly four things it can be.
| Branch | What it means | What it costs if wrong |
|---|---|---|
| Retry | Rerun the change against the hosts that did not get it | Compounds the damage on hosts you did not understand |
| Roll back | Return the converged hosts to the previous state | A second fleet-wide change, at night, under pressure |
| Quarantine | Accept the split, isolate the affected hosts, continue tomorrow | The split becomes permanent if the list is not owned |
| Investigate | Change nothing until the cause is known | Every minute of a live incident where the change was the cause |
Nobody chooses well among four options at 03:00 with a half-converged fleet in front of them and a channel asking for updates. The purpose of this lesson is to move the choice earlier: the criteria go into the change plan, before the run, so that at 03:00 the work is matching evidence to criteria rather than inventing them.
Retry
Choose when: the cause is understood, the fix is in place, and the play is rerun-safe against the specific hosts you are targeting.
Evidence required:
- A named cause for the failures, not a category. “Package lock
contention on hosts whose
apt-daily-upgrade.timerfired at 02:31” is a cause. “Transient errors” is not. - The per-task rerun audit, completed.
- A
--check --diffrun against the retarget list showing per-host what remains to be done. - Stuck resources cleared first: half-finished package transactions, held locks, services in a transitional state.
Do not choose when: the failures are heterogeneous. Thirty hosts failing thirty different tasks is not one problem with one retry; it is a fleet that does not match the play’s assumptions, and retrying tests the same assumptions again.
Roll back
Choose when: the converged hosts are demonstrably worse than the unconverged ones, and a reversal path exists that you have tested.
Evidence required:
- A specific harm on the 220, observed rather than feared. Error rates up, latency up, a service failing, a dependency broken.
- A reversal that is a designed artefact: the previous package versions pinned and available, the previous config in version control, the backup taken by the play itself before it changed anything.
- The knowledge that rolling back is itself a fleet-wide change with the same blast radius as the one that just failed.
Do not choose when: the harm is hypothetical. “Half the fleet is on the new config” is a consistency problem, not a harm, and consistency problems are usually better solved by finishing than by reversing — reversing means touching 220 working hosts to fix 80 that are not.
Quarantine
Choose when: the converged hosts are healthy, the affected hosts can be isolated from traffic or from downstream dependencies, and the remaining work can wait for daylight.
This is the branch that is under-chosen, because it feels like not solving the problem. It is frequently the correct answer, and it has one absolute requirement.
Evidence required:
- The 220 verified healthy against the actual service, not the recap.
- A way to isolate: remove the affected hosts from the load balancer, exclude them from the next change, mark them in the inventory.
- A written list with an owner and a date. Without this, quarantine is not a decision, it is forgetting with extra steps.
# inventory/prod/quarantine.yml
all:
children:
quarantine_2026_08_11:
hosts:
app-047: {}
app-112: {}
app-203: {}
vars:
quarantine_reason: 'Partial patch 2026-08-11, state unverified'
quarantine_owner: 'platform-oncall'
quarantine_review_by: '2026-08-14'- name: Application configuration
hosts: 'appservers:!quarantine_2026_08_11'
become: true
serial: '10%'An inventory group is a better quarantine record than a wiki page because it is enforced rather than advisory: the next person to run the play excludes the hosts whether or not they read the incident notes.
Investigate
Choose when: you cannot describe what happened, or when the change itself is a plausible cause of a live problem.
Evidence required: none. This is the branch you choose because you lack evidence, and it is the correct default when the other three criteria are unmet.
Investigating is not passive. It means: stop the run if it is still going, freeze the fleet against further automated change, capture the evidence before it decays, and go look at hosts. What it does not mean is applying changes while thinking.
Who decides
The four branches do not carry the same authority.
| Branch | Who can decide | Why |
|---|---|---|
| Investigate | Anyone, unilaterally | It changes nothing; it can never be the wrong first move |
| Quarantine | The operator, with a record | Reversible, low blast radius, but creates an obligation someone must own |
| Retry | The operator if the cause is named and the play is safe; otherwise escalate | It is a production change with real blast radius |
| Roll back | Escalate. Always. | It is a second fleet-wide change against healthy hosts, decided under pressure |
Rollback deserving an escalation is not bureaucracy. It is the branch where an individual under stress can turn a partial failure affecting 80 hosts into a full outage affecting 300, and the cost of a two-minute phone call is much lower than the cost of being wrong.
The criteria belong in the change plan
Write them before the run, when nothing is on fire. A usable section is short:
change: patch-and-config-2026-08-11
blast_radius: 300 hosts, appservers, serial 10%
abort_criteria:
- more than 5% of any batch fails
- any host becomes unreachable after the firewall task
- service health check fails on any converged host
on_partial_failure:
retry_if: >-
a single named cause accounts for the failures, the play passes the
rerun audit, and check mode against the retarget list is clean
rollback_if: >-
converged hosts show a measured regression in error rate or latency
AND the pinned previous versions are available
quarantine_if: >-
converged hosts are verified healthy and the affected hosts can be
taken out of rotation until 2026-08-14
otherwise: investigate
rollback_authority: platform-lead or delegate
rollback_tested_on: staging, 2026-08-04The last two lines do most of the work. rollback_authority means
nobody has to work out who to call. rollback_tested_on means the
rollback path is a thing that has been executed rather than a paragraph
somebody wrote.
Knowledge check
Knowledge check · 4 questions
Q1. A play that reconfigured the host firewall left 50 hosts unreachable, clustered in the later batches. What is the correct first action?
Q2. Which conditions must hold before rollback is a branch that actually exists tonight? Select all that apply.
Q3. Why is quarantine described as the under-chosen branch?
Q4. Retrying before capturing the four host lists and the per-task failure histogram destroys evidence you may need.
Passing score: 75%. Answers are checked in this browser.