Runbook — running chaos tests¶
Audience: SRE on a chaos game-day, or an operator vetting a brand-new host before declaring it "in service."
Owner: SRE rotation. Chaos runs must be announced ≥24h ahead in the operator channel and recorded in the post-run log.
When to run¶
| Trigger | What to run | Where |
|---|---|---|
| New host being added to fleet | Full catalogue (#1–#12) | Staging clone of new host, not the live host |
| Quarterly resilience review | Full catalogue | Dedicated chaos host |
| After a real incident | The scenario(s) matching the incident's failure class | Staging |
| After changing the persistence/migration/backup code paths | #1, #7, #9, #10 minimum | Staging |
Before a release that bumps MAID_DRAIN_TIMEOUT_S or MAID_TICK_RATE |
#1 + #11 | Staging |
Never run any chaos scenario on a host that is currently serving real players. The catalogue assumes the operator has at minimum a staging clone and a way to redirect player traffic away first.
Prerequisites¶
- Opt-in gate set. Every test in
tests/chaos/is no-op unlessMAID_CHAOS_ENABLE=1is exported:
-
Target host identified. Use a host whose hostname starts with
chaos-orstaging-. The operator handbook reserves these prefixes for non-production. -
Backup taken. Run a full backup and verify it (
deploy/scripts/backup.sh verify) before injecting any state-mutating chaos. -
Alert pause arranged. Silence the noisy alerts that you expect to fire (the chaos run itself will fire them and you don't want the on-call drowning in pages from your own test):
# Example for an Alertmanager-based stack:
amtool silence add alertname=MaidHealthDegraded \
--duration 2h --comment "chaos run @qworg"
- Game-day buddy. Pair with another operator who is not running the chaos. They watch dashboards and call abort if real traffic is affected.
Execution¶
Each scenario has a documented entry in chaos catalogue with five fields:
- Scenario — what to break
- Expected behavior — what should happen
- Observable signals — what to watch (metric / log / event)
- Recovery procedure — how to put the world back
- Validation script — executable harness (✅) or manual steps (🟡)
Workflow for a single scenario:
# 1. Pre-run baseline.
curl -s "http://${HOST}:9090/api/v1/query?query=maid_health_status" | jq
# 2. Run the validation script (or follow manual steps).
MAID_CHAOS_ENABLE=1 bash tests/chaos/test_kill_during_save.sh
# 3. Check the observable signals match the expected behavior.
journalctl -u maid-engine@chaos.service -n 200 --no-pager | tail -50
# 4. Run the recovery procedure if the script didn't restore state.
# 5. Re-baseline. The metric you watched in step 1 must return to
# its starting value within the runbook's recovery time (RTO).
# 6. Record the result in the chaos log (see "Recording" below).
For the full catalogue run, iterate through scenarios #1–#12 in order. Stop and triage at the first scenario whose expected behavior did not occur — that is a real resilience defect.
Recording¶
Append a line per scenario to /var/log/maid/chaos.log:
2025-01-15T14:22:01Z scenario=1 operator=qworg buddy=alex result=pass notes="drain in 8.2s"
2025-01-15T14:31:44Z scenario=2 operator=qworg buddy=alex result=fail notes="OOM-killer fired but ready-file appeared before persistence caught up; filed ISSUE-1234"
Failures get an issue tracker entry within 24h. Passes get archived into the quarterly resilience report.
Recovery if things go sideways¶
Each scenario in the catalogue has its own recovery procedure linked out to the appropriate runbook. The generic fallbacks, in order:
systemctl stop maid-engine@chaos.service— quench the engine first.nft -a list rulesetthennft delete rule ... handle <h>— remove any chaos firewall rules.umount /var/lib/maid/chaos/state(if you mounted a tmpfs for #3 / #10) and restore the underlying mount.pg_advisory_unlock_all()from a fresh psql session — drop any stale advisory locks from #8.chronyc -a makestep— resync clocks after #6.pkill stress-ng— kill any leftover load generators from #11.- Re-mount, restart, verify integrity:
If the host is unrecoverable, treat it as a host-loss event and follow RB18 — host loss / DR: destroy the staging host and rebuild from the bare-metal deployment guide.
Don'ts¶
- Don't run chaos against the live cluster, ever.
- Don't disable the
MAID_CHAOS_ENABLEgate "to save time" — it exists because production CI will eventually run these tests and we don't want them firing then. - Don't silence chaos alerts longer than the planned run window.
- Don't chain destructive scenarios without recovering between each — you'll lose ability to attribute failures.
- Don't skip the recording step — the audit trail is the resilience program's deliverable.
See also¶
- Chaos catalogue — the 12-scenario list with expected behaviors and observable signals.
- SLO / RPO / RTO targets — the numbers each scenario verifies.
- Operator handbook — day-2 operations reference.
- Runbook index — per-symptom recovery procedures.