VyOSLIV · API and AutomationAutomation
Automation anti-patterns — skip review, run-and-pray, no rollback path
What you'll learn
- Recognise each automation anti-pattern in a code review
- Explain the production failure mode that the anti-pattern produces
- Apply the discipline that catches the anti-pattern before it ships
- Replace the anti-pattern with the production alternative
Prerequisites
Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15
Every automation failure mode is an anti-pattern that some operator wrote, some peer review approved, and some pipeline applied. The anti-pattern is consistent across teams and across years: an operator under time pressure takes a shortcut that bypasses one of the production safeguards. The shortcut produces the immediate change; the safeguard’s absence produces the production outage.
This lesson catalogues the seven anti-patterns the RunBook Academy has seen repeatedly:
- Skip review — the operator merges a change without a peer review.
- Run-and-pray — the operator applies the change without a smoke test.
- No rollback path — the operator does not know how to revert the change if it fails.
- No validation — the operator applies the change without verifying the change had the intended effect.
- Manual override — the operator makes a manual change to the router outside the pipeline.
- Undocumented change — the operator makes a change without a ticket.
- Untested playbook — the operator runs a playbook in production without testing it in a lab first.
Each anti-pattern has a discipline that catches it and a production alternative that replaces it.
Anti-pattern 1: skip review
Symptom: the operator merges a pull request without a peer review. The merge is performed by the same operator who opened the PR.
Failure mode: a typo or a misunderstood intent is applied to the router. The post-incident review cannot defend the change because no second operator examined it.
Discipline that catches it: branch protection rules in the Git platform. The rules require reviewer approval before merge. Merges without approval are blocked.
Production alternative: every change has a peer review. The review examines the diff, confirms the implementation matches the intent, and approves or requests changes.
Anti-pattern 2: run-and-pray
Symptom: the operator applies the change and hopes
it works. The smoke test is skipped or --skip-smoke-test
is used.
Failure mode: a behavioural error (e.g. wrong BGP peer IP, missing authentication) is applied. The change is in the running configuration; the network behaviour is broken.
Discipline that catches it: a mandatory smoke test in the pipeline. The smoke test runs after the apply; if it fails, the pipeline rolls back.
Production alternative: every change has a smoke test. The smoke test verifies that the change had the intended effect (e.g. BGP session is Established, OSPF adjacency is Full).
Anti-pattern 3: no rollback path
Symptom: the operator makes a change without verifying that the change can be reverted. The previous configuration revision is not saved; the rollback procedure is not documented.
Failure mode: the change fails. The operator cannot revert. The router is in a half-configured state; the outage extends.
Discipline that catches it: the commit history
always has the previous revision available. The
rollback N command reverts to the previous revision.
Production alternative: every change is preceded by
a save operation (or a commit that automatically
saves). The previous configuration revision is always
available. The rollback procedure is documented in the
ticket.
Anti-pattern 4: no validation
Symptom: the operator applies the change and closes the ticket without verifying. The change is applied; the network behaviour is broken.
Failure mode: the change is in the running configuration but the routing protocols are not established. The operator closes the ticket; the change is “successful” in the change log but the network is broken.
Discipline that catches it: a mandatory post-deploy verification in the ticket close workflow. The ticket cannot be closed without a verification record.
Production alternative: every change is followed by a post-deploy verification that records the commands run, the expected output, and the actual output.
Anti-pattern 5: manual override
Symptom: the operator makes a manual change to the router outside the pipeline. The change is not in Git.
Failure mode: the next render-and-apply reverts the manual change. The manual change is lost; the operator is surprised. Drift detection (which runs nightly) reports the divergence.
Discipline that catches it: drift detection. A nightly job renders the current configuration and compares to the router state. Any divergence is flagged.
Production alternative: the pipeline is the only path to the router. Manual changes are forbidden. The router’s running configuration is expected to match the rendered output; drift is a defect.
Anti-pattern 6: undocumented change
Symptom: the operator makes a change without a ticket. The commit message has no ticket reference; the audit log has no ticket ID.
Failure mode: the post-incident review cannot find the intent. The change is in the running configuration; the rationale is missing.
Discipline that catches it: a pre-commit hook that checks for a ticket ID in the commit message. Commits without a ticket ID are rejected.
Production alternative: every change has a ticket. The ticket captures the intent, the implementation, the rollback plan, and the risk. The commit message references the ticket ID.
Anti-pattern 7: untested playbook
Symptom: the operator runs a playbook in production without testing it in a lab first. The playbook has never been applied to a router.
Failure mode: the playbook has a bug (wrong module parameter, wrong variable, wrong template) that the production router surfaces. The router is misconfigured; the operator must debug in production.
Discipline that catches it: a lab environment that mirrors the production routers. The playbook is applied to the lab first; the lab is the operator’s defence against a playbook bug.
Production alternative: every playbook is tested in a lab before it is applied to production. The lab environment mirrors the production configuration; the playbook’s behaviour in the lab predicts its behaviour in production.
The discipline
The discipline is a set of safeguards, each catching a different anti-pattern:
flowchart TB
ANTI[Anti-pattern] -->|caught by| DISC[Discipline]
DISC --> D1[Branch protection\nskip review]
DISC --> D2[Mandatory smoke test\nrun-and-pray]
DISC --> D3[Commit history\nno rollback path]
DISC --> D4[Post-deploy verification\nno validation]
DISC --> D5[Drift detection\nmanual override]
DISC --> D6[Pre-commit ticket check\nundocumented change]
DISC --> D7[Lab environment\nuntested playbook]
The diagram shows the mapping: each anti-pattern is caught by a specific discipline. The discipline is the operator’s defence against the anti-pattern.
Failure modes
Discipline decays
The team implements all seven disciplines. Six months later, the team is under time pressure; the operator skips the peer review “just this once”. The change is applied; the typo is caught in production. The operator realises the discipline decay was the cause.
Diagnostic: the Git commit log shows merges without
reviews; the smoke test was skipped with
--skip-smoke-test; the ticket was closed without
verification.
Fix: re-implement the disciplines. The defensive idiom: the disciplines are configured in the platform (branch protection, pre-commit hooks, CI/CD pipeline), not in the operator’s discipline. The operator cannot bypass a configured safeguard.
Discipline is implemented inconsistently
The team implements the disciplines for some changes but not others. The new-routing-team uses the full discipline; the existing-team uses only the render-and- apply. The two teams produce different change quality.
Diagnostic: the Git commit log shows different change patterns between teams.
Fix: standardise the discipline across the team. The defensive idiom: the discipline is the same for every change; the platform enforces the discipline; the operator cannot bypass it for a specific change.
Discipline is documented but not enforced
The team writes the discipline in a wiki page. The wiki page is not enforced; the operator can bypass the discipline.
Diagnostic: the wiki page describes the discipline; the change log shows the discipline is not followed.
Fix: enforce the discipline in the platform. The defensive idiom: branch protection rules require reviewer approval; pre-commit hooks require ticket IDs; the CI/CD pipeline requires smoke tests. The operator cannot bypass a configured safeguard.
Rollback
The anti-patterns themselves do not require a rollback;
they require the discipline that prevents the
anti-pattern. The rollback is the standard VyOS
mechanism (rollback N and commit).
Production discipline
Cross-course references
LIV-VyOS-Automation(vyos-liv-03-config-as-code,vyos-liv-04-automated-validation,vyos-liv-05-change-management) cover the configuration-as-code pipeline, the validation patterns, and the change management workflow that the anti-patterns bypass.LII-VyOS-Troubleshooting(vyos-lii-06-troubleshooting-anti-patterns) covers the troubleshooting anti-patterns that the automation anti-patterns often mask.- The Google SRE Book chapter on automation covers the same anti-patterns from a different angle.
Quiz
Knowledge check · 4 questions
Q1. Which automation anti-pattern is the most common cause of production outages in the RunBook Academy experience?
Q2. An emergency change may skip the peer review if a second operator is not available.
Q3. An operator under time pressure makes a manual change to edge-01 to fix an urgent BGP issue. The change is applied via SSH `configure` / `set` / `commit`. The change is not in Git. The next morning, the nightly drift detection reports the divergence. The render-and-apply reverts the manual change. The BGP issue returns. What is happening and what is the discipline failure?
An operator makes a manual change to edge-01 to fix an urgent BGP issue. The change is not in Git. The next morning, the render-and-apply reverts the manual change.
Q4. An operator runs a playbook in production without testing it in a lab first. The playbook has a bug — the wrong variable is used in a `set protocols bgp neighbor` command. The bug is applied to 50 production routers. The BGP sessions on all 50 routers are down. What is the anti-pattern and what is the discipline that prevents it?
An operator runs an untested playbook in production. The playbook has a bug. The bug is applied to 50 production routers. The BGP sessions are down.
Passing score: 75%. Answers are checked in this browser.