The Monthly Standardization Playbook That Broke Twelve Leaf Pairs
An Ansible codebase manages 180 Nexus 9000 switches. One playbook uses nxos_config with a Jinja source template and replace: block to standardize Ethernet1/1 through Ethernet1/48 as access ports. The block markers were written by hand. It has run monthly for six months against all 180 devices with no diff review, executed with default settings (no serial, no max_fail_percentage, no check mode). Last week the run failed on switch 17 of the first batch because of an SSH timeout; the operator re-ran it from the top. On Monday, twelve leaf switches reported vPC peer-link flaps, and four of them now carry different STP and MTU settings from their vPC peers.
1. Explain mechanically how a playbook whose stated purpose is standardizing access ports removed vPC configuration, and why the second run made things worse.
Read the worked answer
replace: block is a overwrite, not a merge.
It takes everything between the begin and end markers and substitutes the rendered template output. Any line that exists inside those markers but is absent from the template is deleted. The template contains descriptions, switchport mode, access VLAN, and MTU - it does not contain vpc 10, channel-group, or spanning-tree port type edge trunk. On switches where the hand-written markers happened to span interfaces that are vPC member ports, the render silently deleted the vPC configuration from those ports.
The second run amplified the damage because of partial application. With default settings there is no serial and no max_fail_percentage, so the run had already completed on sixteen devices when it timed out on seventeen. Re-running from the top applied the template to a different subset again. Net effect: within a vPC pair, one peer has the new MTU and STP settings and the other does not.
That divergence is exactly what produces peer-link flaps - vPC type-1 consistency checks MTU and STP port type, and a mismatch puts the peer-link or member ports into a suspended state. The flapping is not a side effect; it is the predictable output of half-applying a global parameter across a pair.
2. Identify the controls that were missing and rank them by how much damage each would have prevented.
Read the worked answer
Ranked by damage prevented:
- A diff review before write.
--check --diffon a single canary switch would have printed every- vpc 10line as a deletion. This alone stops the entire incident, because the operator sees the deletion before it happens anywhere. Highest value by a wide margin. - Configuration backup as part of the task (
backup: yesor an out-of-band pre-change capture). This does not prevent the incident but converts recovery from reconstruction to restore, and it makes the blast radius bounded. - Blast-radius control:
serialwith a small batch size andmax_fail_percentage: 0. This turns a timeout on switch 17 into a hard stop rather than a half-applied fabric, and prevents the re-run from re-shuffling which devices are configured. - Scoping the template to intent, not to a block. Excluding vPC member ports from the managed range, or using resource modules that manage declared properties rather than replacing a text block, removes the class of error entirely.
- Idempotency verification: a second run reporting zero changes on a device that was already compliant would have flagged the divergence in early months, before twelve pairs were affected.
Note the ordering principle: the controls that put a human between the render and the device rank above the controls that merely make recovery faster.
3. It is Monday morning and four pairs are divergent. Describe the recovery sequence and what you must verify before resuming automation.
Read the worked answer
Do not re-run the playbook. Freeze it first.
- Freeze automation. Disable the scheduled job and any pipelines that call this playbook. A scheduled run landing mid-recovery will re-apply the faulty template to devices you have just fixed.
- Inventory divergence per pair, not per device. On each of the four pairs run the vPC consistency check to see which parameters disagree - MTU and STP port type are named in the symptoms, but check VLANs and port-channel settings too. A pair is only recovered when the check is clean, not when the config looks similar.
- Recover the secondary side first, leaving the primary untouched where possible. Bring the pair into consistency with the vPC primary in a controlled window, since restoring the peer-link brings suspended member ports back and can cause a broadcast/STP reconvergence.
- Restore from backup where reconstruction is ambiguous. If the deleted
vpcandchannel-grouplines cannot be reproduced exactly from another pair's config, restore the pre-change config instead of hand-editing; hand-editing under pressure is how the second divergence gets introduced. - Fix the template and the markers so the managed range cannot include vPC member ports, and delete the hand-written markers in favour of a machine-generated or resource-module approach.
- Resume with a canary. Run
--check --diffagainst two switches in different vPC pairs, read every deletion line, then apply to the canary pair withserial: 1andmax_fail_percentage: 0, verify vPC consistency, and only then widen.
The resumption gate is not 'the playbook ran green' - it is 'the diff showed no deletions of vPC, channel-group, or STP configuration on a canary pair, and the consistency check is clean after apply.'