Per-Feature Rollback Implementation
Rollback Tag Convention
Per-feature rollback uses Ansible tags in
cleanup.yml. Convention:--tags <feature>-rollbackruns the inverse of--tags <feature>.Feature Tags follow this pattern:
Feature Tags (current) ├── Apply: openwrt-security, openwrt-vlans, openwrt-dns, openwrt-mesh └── Rollback: openwrt-security-rollback, openwrt-vlans-rollback, openwrt-dns-rollback, openwrt-mesh-rollbackApply tags go in
site.ymlplays. Rollback tags go incleanup.ymlplays. Rollback plays are gated by their rollback-specific tags (e.g.,openwrt-security-rollback) — you must pass--tagsexplicitly to invoke them. NEVER use Ansible'sneverspecial tag.
OpenWrt UCI Rollback Pattern
UCI changes on OpenWrt are atomic per
uci commit. ALWAYS group related UCI changes into a single commit. Rollback reverses them withuci deleteoruci setto defaults, thenuci commit.Per-feature rollback pattern (OpenWrt UCI):
# In playbooks/cleanup.yml - name: Rollback security hardening hosts: openwrt tags: [openwrt-security-rollback] gather_facts: false tasks: - name: Remove banIP and revert SSH config ansible.builtin.raw: | opkg remove banip 2>/dev/null uci delete dropbear.@dropbear[0].PasswordAuth 2>/dev/null uci delete dropbear.@dropbear[0].RootPasswordAuth 2>/dev/null uci commit dropbear /etc/init.d/dropbear restartRollback plays are gated by
when: rollback | default(false) | bool. Invoke via:ansible-playbook cleanup.yml --tags openwrt-security-rollback -e rollback=true.
Package Installation Rollback
- Package installation rollback uses
opkg remove. ALWAYS list installed packages in the feature's rollback procedure.
State Tracking for Rollback
deploy_stamprecords what ran. Rollback tasks MUST checkansible_local.vm_builds.playsto determine what needs undoing. NEVER attempt to roll back a feature that was never applied.Use deploy_stamp for idempotent feature application — skip expensive operations when the feature is already at the current version.
Auth State Rollback
Rollback MUST fully restore the baseline auth/connection state. If a feature deploys SSH keys and disables password auth, rollback MUST re-enable password auth AND clear the root password (restoring empty-password baseline).
Partial auth rollback leaves the system in an undefined state — neither key nor password works.
cleanup.sh Integration
cleanup.shsupports arollbacksubcommand that delegates tobuild.py:./cleanup.sh rollback security test.env # → build.py --playbook cleanup --tags openwrt-security-rollbackThe subcommand maps the feature name to the rollback tag using the convention
openwrt-<feature>-rollback.
Stub Prevention
- NEVER add stub plays/rollback for features that depend on unimplemented projects. Integration plays are owned by the downstream project that creates the dependency. Keep
site.ymlandcleanup.ymlfree of dead code.