Newer
Older
openstack-caracal-dc-dc / docs / audit / container-elim-pass / pass1-w1-redeploy-teardown.md

Pass 1 -- Worker W1.1: redeploy/teardown PLANNING under the confirmed Option-1 target

Author: W1.1 (Phase 1, container-elimination pass). Date: 2026-08-09. Scope: what the CONFIRMED Option-1 target topology (pass0-admin-report.md Section 7a) changes in the teardown and redeploy PLANNING ARTIFACTS -- runbooks/dc-dc-teardown-rollback.md, the runbooks/dc-dc-phase0..6*.md runbooks, and how D-143's re-IP interleaves with the container-elim change-set in the redeploy sequence. READ-ONLY. No mutation, no live commands. Every claim below is anchored to a path:line read this session; where a value is not yet knowable it is marked UNKNOWN with what resolves it.

Reminder of the confirmed target (do not re-derive): flat node VMs directly on vcloud libvirt; vvr1-dcN ELIMINATED; a small non-hypervisor vr1-dcN-client VM (metal-admin + transit legs) inherits the D-138 client role + that DC's credential residencies; MAAS region stays on vr1-dcN-maas-01 unchanged; rack-controller remainder / D-131 forwarder / artifact service placement is OPEN (client VM vs maas-01, carried into this phase per Section 6 item 3 of pass0-admin-report.md); cross-DC isolation (a) is a REQUIRED Phase-1/2 design deliverable (a new vcloud-level host isolation control); this rides D-143 but must stay DISTINGUISHABLE from it.


1. The teardown-primitive answer

Today: runbooks/dc-dc-teardown-rollback.md's whole structure is built on the D-123 Model-B TWO-ROOT/TWO-HOST shape -- an OUTER root on vcloud that creates vvr1-dcN, and an INNER root run FROM THE OFFICE1 HEADEND (voffice1) via qemu+ssh into the containment VM (lines 26-65, the "MODEL B RESHAPE" banner; lines 136-152, "TWO CLONES, TWO HOSTS"). D-122's site-down lever is explicitly one object: virsh destroy vvr1-dcN (line 48). Every Path (A/B/C/M) is written against this shape.

Under Option 1, the two-root/two-host shape COLLAPSES to one root on vcloud. There is no containment VM to hold an inner libvirt, so there is no qemu+ssh provider dial, no inner state file on voffice1, and no D-122 single-object site-down (that lever is explicitly named a "REAL D-123 regression to carry honestly" in pass0-admin-report.md row 9). The teardown primitive becomes:

A single-root, module-scoped tofu destroy per DC, run entirely on vcloud -- tofu destroy -target=module.vr1_dcN_planes -target=module.vr1_dcN_node -target=module.vr1_dcN_wan -target=module.vr1_dcN_opnsense -target=module.vr1_dcN_client -target=module.vr1_dcN_storage (module names illustrative -- Phase 2/W2.1 owns the real post-flattening module names), OR (preferred, since a flat root holding exactly one DC's resources needs no -target at all, same logic the current runbook already uses for the per-DC INNER root, lines 751-758) one dedicated root per DC so a plain tofu destroy there is inherently scoped -- re-earning the "scope by choosing the root" discipline (current lines 155-168) without a second host.

This is the group-destroy of the vr1-dcN-* domain set, not a single-object destroy -- D-122's convenience is genuinely lost, and Section 5's cross-DC isolation gap (Section 5) is one more reason NOT to try to re-earn it via "add a synthetic wrapper VM back" -- that would just re-import the eliminated pattern. The honest replacement discipline: (a) a tofu-level group-destroy scoped by root/module (safe, plan-reviewable, the mechanism above), and (b) for a "stop this DC's compute NOW" emergency lever (the actual use case D-122's single-virsh convenience served), a SCRIPTED loop over virsh destroy for the named domain set derived from lib-hosts.sh's roster for that DC -- not a manual enumeration. Both are NEW artifacts this pass must hand to Phase 2/4 (tooling + module design), not something already built.

1.1 Per-Path change list

Path Today's assumption (path:line) Option-1 change
"TWO CLONES, TWO HOSTS" preamble (:136-152) Every command runs on $REPO (vcloud, outer) OR $O1_REPO (voffice1, inner substrate roots) COLLAPSES to ONE clone/one host: $REPO on vcloud only. The whole two-host framing is DELETED; $O1_REPO no longer holds a DC substrate root (voffice1 keeps its OWN unrelated Office1 role, D-114 -- untouched, see Section 2)
Path A -- scoped teardown (:154-173, Steps 3-5) "Scope by choosing the ROOT first" between OUTER (vcloud, all 3 sites) and INNER (per-DC, voffice1, qemu+ssh); order = INNER then OUTER, backups from TWO hosts (Step 1, :600-631) Root choice becomes: OUTER (shared: Office1 + mesh + both DC-storage-pool-parent, if any survives flat) vs. a PER-DC flat root holding that DC's planes/nodes/edge/client VM. Order collapses to ONE apply per DC (no inner/outer split); Step 1's backup is ONE state file per DC root, taken on vcloud only. Step 3's module table (:765-775) is rewritten with post-flattening module names (Phase 2/W2.1 -- names not yet minted, UNKNOWN pending that design)
Path A -- Step 2 (MAAS census) (:635-747) "WHERE: from the OFFICE1 HEADEND ... the region MAAS and its CLI profile live there" (:655-658); LENS 2 sources lib-hosts.sh boot-MAC roster via lib_hosts_select_dc MAAS region is UNCHANGED (stays vr1-dcN-maas-01, confirmed at the Phase-0 gate) -- this step's WHERE clause survives if maas CLI still runs from voffice1 (D-128 Plane 2), but the machine roster it's checking against no longer includes the containment VM itself (there is none) and now includes vr1-dcN-client. Mechanically the SAME two-lens structure, refreshed roster
Path A -- Step 4 verify (:838-891) "The DC's node, edge and plane objects live inside the containment VM, so a local virsh on vcloud can never see them" (:858-860); verify INNER half via qemu+ssh from voffice1, OUTER half via local virsh on vcloud (two verify blocks) COLLAPSES to ONE verify block, local virsh on vcloud only -- planes/nodes/edge/client VM are all now vcloud-libvirt-visible directly. The "vcloud-local grep 'passes' against a fully intact DC" caveat (:861-864) becomes MOOT (there is nothing hidden behind a second libvirt any more)
Path B -- full VR1 teardown (:914-957) "everything" = THREE roots on TWO hosts (:920-932) "everything" = N+1 roots (one shared/outer + one per DC, or a single unified root -- module design decides, Phase 2) on ONE host. Verify block (:941-953) drops its qemu+ssh refusal-guard branch entirely
Path M -- juju MODEL teardown (:188-392) Untouched by containment: it is one layer ABOVE substrate (juju model on top of already-provisioned MAAS machines). No qemu+ssh or vvr1-dcN reference in the body UNCHANGED as a procedure. Only its execution-HOST assumption (implicit: wherever juju runs, i.e. the DC rack today) moves with D-138's client-VM re-home -- see Section 3 below (phase4's table, not this runbook)
Path C -- juju CONTROLLER teardown/rebuild (:394-596) Untouched by containment for the SAME reason as Path M -- it operates on MAAS machine records and the juju controller, one layer above substrate. C.1's MAAS census and C.6's tag check are host-agnostic (maas CLI location unaffected: still MAAS-region-side, i.e. voffice1 per D-128 Plane 2, unchanged) UNCHANGED as a procedure. No edit needed in this runbook; the D-138 client-VM re-home is the phase4 change, not this one
Mesh-link teardown (:960-995) Three OUTER-root legs (mesh_vr1_dc0_vr1_dc1, mesh_vr1_dc0_office1, mesh_vr1_dc1_office1) + netem, sharing the D-125 caveat that mesh_vr1_dc0_office1 "carries the live rack<->region transit ... the inner root's own qemu+ssh path" (:981-983) The mesh legs and netem module PERSIST (confirmed non-eliminated, pass0-admin-report.md Sec 1.3). The mesh_vr1_dc0_office1/mesh_vr1_dc1_office1 caveat's WORDING changes: it no longer carries "the inner root's qemu+ssh path" (that's gone) but DOES still carry the vr1-dcN-client's reach to voffice1/MAAS-region and the operator ssh -J path (Section 6 item 5 of pass0-admin-report.md, still OPEN) -- reword, don't delete the caution
"Relationship to D-061" (:86-134) Frames the coordination principle as OpenTofu's resource view vs. MAAS's per-machine view (unaffected by which root creates the resources) UNCHANGED in principle. No containment-specific text here to edit
Rollback decision tree (:998-1069) "Question 0 -- WHICH ROOT failed? There are three" (:1006-1010); item 5's containment-VM-destroy caution (:1059-1067) is written entirely around virsh destroy vvr1-dcN as the reversible site-down lever Question 0 becomes "which DC's flat root" (fewer roots, no inner/outer split). Item 5 needs a REPLACEMENT lever entirely -- there is no single reversible power-off object any more; the nearest analog is a scripted virsh destroy loop over that DC's node-VM domain set (irreversible-feeling but mechanically the same primitive, just N domains instead of 1) -- flag as a NEW tested artifact this pass owes (Section 1 above), not a drop-in rename
Verification footer (:1071-1091) Notes all module/network/pool names were "RE-MEASURED against the tree and the live hosts on 2026-07-29" for the two-root shape The whole footer's provenance is for a shape being eliminated -- a rewritten runbook needs its OWN re-measurement pass against the new flat module tree (Phase 2/4 delivery item, not this planning pass)

Net verdict on this runbook: it needs a REWRITE comparable in scope to the 2026-07-16 "MODEL B RESHAPE" banner that was bolted on for the previous topology change -- likely the same pattern (a prominent "OPTION-1 FLATTEN" banner up top plus the Steps re-grouped), not a line-by-line patch. Paths M and C are the two genuinely LOW-delta paths (they sit above the substrate layer entirely); Paths A/B and the rollback tree carry the real rewrite weight.


2. Per-phase-runbook change list

2.0 What does NOT change

  • runbooks/dc-dc-phase0-vcloud-prep.md -- grep for vvr1-dc/containment/qemu+ssh/ inner root/outer root returns ZERO hits in the body (only a generic qemu+ssh://... example at :113,123 describing the libvirt-URI syntax itself, and libvirt_uri = "qemu:///system" # or qemu+ssh://... -- Step 1 at :364, which is the OUTER root's own provider block, unaffected). This runbook covers vcloud host prep, the D-100 mesh triangle, storage pools, the shared base image -- none of it is containment-specific. No change required.
  • runbooks/dc-dc-phase1-office1-standup.md -- its "containment VM" is voffice1 under D-114, a DIFFERENT decision than D-123's Model-B DC containment (:9,13,44-47,313-337 -- D-114 is cited by name throughout, never D-123). voffice1 simulates the Office1 FACILITY and hosts MAAS-region/LXD for MAAS-composed service VMs (NetBox, tailscale) -- it is not the object the container-elim pass targets, and Phase-0's scope explicitly named the container layer as vvr1-dcN only (SCOPE-AND-EXECUTION-PLAN.md Sec 2, pass0-admin-report.md Sec 1.3 "It is NOT: ... the DC edge ..." -- Office1 wasn't even in scope). No change required for THIS pass. Flag for the record: D-114's own containment pattern is architecturally the same shape D-123 used, and if the operator's "eliminate the container layer" intent is read as broader than the Phase-0 gate scoped it, that is a SEPARATE decision outside this pass's mandate -- not assumed here.

2.1 runbooks/dc-dc-phase2-tofu-dc-substrate.md -- the largest single change

This runbook IS the two-root apply sequence, and its "D-123 MODEL B RESHAPE" callout (:144-204) is the direct predecessor of the change this pass makes. Per-step:

Step (path:line) Today's assumption Option-1 change
A. OUTER apply (:151-152) -- creates + sizes vvr1-dc0 (~480 GiB, expose_nested_virt=true) + transit Sizes and provisions the CONTAINMENT VM itself Sizes and provisions the FLAT node-VM set + edge + vr1-dcN-client directly. expose_nested_virt=true DROPS (no nested libvirt needed anywhere in this DC -- confirm no OTHER consumer needs nesting before deleting the flag; none found in Phase-0's inventory). Overhead sizing (~480 GiB minus node/edge sizes) is FREED -- ties to the owed FIT recompute (pass0-admin-report.md Sec 8.2)
B. BOOTSTRAP GATE -- site-headend-install.sh --role rack --host-nodes ... (:153-157) A DISTINCT stage between the two applies: enrolls the rack to the Office1 region AND makes vvr1-dc0 a nested libvirt host (kvm nested=1, inner pool dir, AppArmor, SEC-010 transit FORWARD-drop). GATE: --check must pass THIS STAGE IS ELIMINATED WHOLESALE. There is no "make a VM a nested libvirt host" step because there is no nested libvirt host. What SURVIVES from its payload, re-homed: (i) rack enrollment to the Office1 region -- lands wherever the rack-controller remainder is placed (client VM / maas-01 / retire -- Section 6 item 3 of pass0-admin-report.md, still OPEN, UNKNOWN pending that placement decision); (ii) the SEC-010 transit FORWARD-drop -- REBUILT for the new boundary, not moved (pass0-admin-report.md row 6, "must be REBUILT ... not moved"); this is the SAME control the Phase-0 gate's cross-DC isolation deliverable (handling (a)) needs a new design for -- the two are related but distinct (SEC-010 is transit-leg-scoped; (a) is host-level cross-DC). site-headend-install.sh --host-nodes mode becomes DEAD CODE for VR1 (confirmed pass0-admin-report.md row 6)
C. INNER apply (:158-161) -- provider = qemu+ssh to vvr1-dc0, run FROM voffice1; the 6 planes + wan + edge + inner pool + 9 node VMs A SEPARATE apply, separate state, separate host, gated behind B MERGES INTO STEP A. One apply, one root, one host (vcloud), one state file. The 6 planes / wan / edge / node VMs (now +1 for the client VM) are ALL created by the single OUTER apply -- there is no "inner" any more. Steps 5-6 (wiring modules/opnsense-edge and modules/node-vm calls into main.tf, :129-141) collapse from "authored in the inner root" to "authored directly in the (now singular) root's main.tf"
D. maas-vm-host (Step 9, :162-163,588-640) -- register vvr1-dc0's OWN local qemu:///system virsh to the Office1 region Registers the CONTAINMENT VM's inner libvirt as a MAAS vm-host Registers vcloud's OWN libvirt (already the case for the OUTER root's objects) OR is retired if the flat topology never needed per-machine power_type=virsh registration to change shape -- this step was already DEFERRED (DOCFIX-179) before this pass; Option 1 does not resurrect it, it just removes the "vvr1-dc0's OWN inner virsh" framing since there is no inner virsh
E. netem (Step 11, :164-168) -- runs on vcloud-level mesh bridges, OUTER, already correctly targets the dc0<->dc1 leg, NOT the transit leg that "carries ... the inner root's own qemu+ssh" Already outer-scoped, mostly unaffected The caveat text needs its "the inner root's qemu+ssh" clause reworded (that path no longer exists) but the netem TARGET and mechanism are unaffected -- low-delta edit
D-125 bridge-in (:193-203) -- OUTER creates the vcloud ISP NAT + a 2nd IP-less uplink NIC + br-vr1-dc0-wan bridge on vvr1-dc0; BOOTSTRAP --check verifies the bridge; INNER's vr1-dc0-wan is a BRIDGE (modules/wan-bridge) onto it Exists SOLELY to fix OBS-3 nesting egress -- an artifact of the containment VM being a two-NIC transit-only host with no egress of its own DELETED per pass0-admin-report.md row 3. The DC edge WAN attaches DIRECTLY to the outer vr1_dc0_uplink NAT (same /24, no re-address) -- there is no intermediate host needing a bridge-in fix. modules/wan-bridge becomes dead code for VR1; the BOOTSTRAP --check's bridge-verify clause is deleted with the gate itself
"Sequence" step list (:114-142) Numbered 1-12 against the single-root FRAMING, then regrouped A-E for Model B Needs a THIRD regrouping (or, cleaner, a fresh linear list -- Option 1's flat shape doesn't need the A-E lettering since there's no bootstrap-gate seam to letter around). This is the step-list equivalent of the runbook-wide rewrite flagged in Section 1
DC standup definition-of-done (:822-887) References "the containment/service net" MEASUREMENT and "containment ssh shape" (:830-833) and objects "created by site-headend-install.sh --host-nodes" (:842) Both references need re-homing to "how vcloud reaches the DC's node-VM planes directly" and drop the --host-nodes citation (dead per row above)
Step 13 backup (:741-822) Backs up "the inner tfstate" via voffice1 (:764-804), noting a qemu+ssh-only provider dependency is "strong[er]" evidence of correctness (:764) Backs up ONE state file (the flat per-DC root), taken and stored on vcloud -- the voffice1-hop and its "no key in state" argument are MOOT (no qemu+ssh provider block exists to make that argument about)

Net verdict: Phase 2 needs the SAME weight of rewrite as its own prior D-123 reshape -- arguably heavier, since this pass ELIMINATES a whole apply stage (B) rather than adding one.

2.2 runbooks/dc-dc-phase3-maas-enlist-deploy.md

  • :424,430 -- ssh -i ~/vr1-dcN-creds/... -J voffice1 jessea123@<dcN-rack-transit-ip> 'sudo bash -s' -- check dcN < scripts/dc-mirror.sh (dc0) / dc-cache-proxy.sh (dc1). Today's assumption: the jump target is the rack transit IP, i.e. the CONTAINMENT VM (vvr1-dcN's own transit leg, per lib-hosts.sh's VIRSH_POWER_ADDRESS). Option-1 change: the jump target becomes vr1-dcN-client's transit IP -- the artifact-service check (dc-mirror/dc-cache-proxy) still runs via SSH-through-voffice1 into the DC, but the far end of that hop is a different (non-hypervisor) VM. The artifact-service PLACEMENT itself (client VM vs. vr1-dcN-maas-01 vs. retire) is the OPEN item from pass0-admin-report.md Section 6 item 3 -- if it lands on maas-01 instead, this whole SSH target changes to that VM's address, not the client VM's. UNKNOWN pending that placement ruling; do not pick one here.
  • Everything else in Phase 3 (MAAS enlist/commission/deploy of the node fleet, Steps 1-7 generally) is about MAAS machine-level operations against a fleet that is already flat from MAAS's point of view TODAY (per-machine power_type=virsh, no pod) -- pass0-admin-report.md confirms this is NOT a two-root/containment-keyed concern (row 4/5: only the POWER ADDRESS changes, the mechanism is topology-agnostic). Low delta beyond the two SSH-target lines above.

2.3 runbooks/dc-dc-phase4-juju-bundle-per-dc.md

  • :158-185, the "RUN LOCATION" table -- this is the runbook's own record of getting D-138 wrong once already (superseded text quoted at :169-178: "Every juju and maas command runs on voffice1" was WRONG; D-138 moved juju/openstack CLI onto "THIS DC's RACK"). Under Option 1, "THIS DC's RACK" is retired vocabulary -- the concrete host D-138's principle points at becomes vr1-dcN-client (per pass0-admin-report.md Sec 3.3, Option 1's client VM is "consistent with D-138's principle"; the concrete-host CHANGE still needs recording, Phase 4's [ARCH] decision). This table needs a THIRD correction pass: row 1 ("juju/openstack CLI") -> runs on vr1-dcN-client, not "the rack" (the rack as a distinct host no longer exists); row 2 (maas/NetBox/tofu) stays on voffice1, UNCHANGED (D-128 Plane 2 survives -- MAAS region and NetBox are not containment-layer objects); row 3 (never vcloud) UNCHANGED.
  • :180-185, the staged-scripts caveat -- "the rack has NO repo clone" and needs ~/repo-stage/scripts/ staged there. This caveat TRANSFERS verbatim to vr1-dcN-client (still a non-repo-clone host by design, same staging discipline needed) -- no logic change, just a re-pointed noun.
  • :840-848, the "considering destroying anything BELOW the juju layer" caution -- names "the containment VM, the DC's libvirt resources, MAAS records" and points at the (currently Model-B-shaped) teardown runbook. Needs updating to point at the REWRITTEN teardown runbook (Section 1 above) and drop the containment-VM noun -- the caution's PRINCIPLE (don't reach for a substrate destroy while nodes are MAAS-enrolled) is unchanged.
  • Path M and Path C content itself (the juju model/controller procedures phase4 delegates to the teardown runbook) needs NO change here -- confirmed low-delta in Section 1.

2.4 runbooks/dc-dc-phase5-dr-failover-drill.md

  • No vvr1-dc/containment/qemu+ssh hits (grep confirmed). Its only execution-host reference worth flagging is INDIRECT: it delegates the per-DC deploy command to Phase 4 (:430-433) and otherwise operates at the juju/openstack layer, which is D-138-scoped (client VM under Option 1) rather than containment-scoped. No direct edit required by container-elim; it inherits whatever Phase 4's table says.

2.5 runbooks/dc-dc-phase6-designate-cos-magnum.md

  • :437-444 -- "juju is ABSENT on vcloud ... Run them from the Plane-2 host (voffice1) per D-128" and "CHECK (read-only) -- from the Office1 headend (voffice1)" immediately precedes a juju status -m ... command. This is ALREADY WRONG independent of the container-elim -- it predates phase4's own D-138 correction (juju runs on the DC's execution host, not voffice1; pass0-admin-report.md and phase4's :174-178 both confirm juju controllers on voffice1 returns "No controllers registered"). Flagging here because the SAME fix phase4 needed (rack -> client VM) applies to this line too, and both should be corrected in the SAME pass since they share the root cause (a stale D-138 pointer). Not itself a NEW container-elim delta, but a pre-existing defect this pass's rewrite sweep should not leave behind.

2.6 runbooks/dc-dc-office1-service-reip.md

  • Entirely Office1-scoped (voffice1's own MAAS-composed LXD VMs -- NetBox, tailscale). No vvr1-dcN reference; out of this pass's scope (D-114, not D-123).

3. D-143 (re-IP) vs. container-elim: keeping the two axes distinguishable in the redeploy sequence

D-143's OWED EXECUTION list (docs/design-decisions.md:8163-8174) is FIVE items, all address-only:

  1. NetBox apex -- new B2 role Cloud -- VR1 rebuild owning 10.13.0.0/16; re-carve VR1 prefixes/VIPs/ranges under it, octet-preserving.
  2. scripts/lib-net.sh -- flat defaults STAY 10.12; vr1-dc0/vr1-dc1 arms get full 10.13 literal blocks; fix the stale ":124-134" comment.
  3. 10.13 naming-collision DOCFIX (netbox/README.md:49, a test literal).
  4. D-124 transit routes re-point + rack statics shift (10.12.8.2 -> 10.13.8.2, etc.).
  5. Teardown must REVOKE the dc0-substrate credentials before redeploy.

None of these five items touch topology -- they are a value substitution (12->13) plus one NetBox role-model addition. The container-elim change-set is orthogonal: it changes WHICH objects exist and WHERE they run, not what numbers they carry. Concretely, keeping them distinguishable in the redeploy plan means:

  • Sequence within one redeploy, not two redeploys. Since both changes ride the SAME teardown+rebuild, the interleave is: (i) teardown the CURRENT 10.12 Model-B checkpoint (Section 4 below) -- an ADDRESS-AGNOSTIC, TOPOLOGY-AGNOSTIC action (you're destroying objects, not re-carving them); (ii) apply D-143 item 1 (NetBox apex) and item 2 (lib-net.sh literal blocks) as the FIRST rebuild inputs -- these are pure data, no topology dependency, so they can be done before or independent of the module rewrite; (iii) rebuild against the Option-1 flat module design (this pass's Phase 2/4 deliverable), consuming the NEW 10.13 literals from step (ii) -- the flat root's tfvars/module calls reference lib-net.sh's 10.13 arm the same way the old two-root shape referenced its 10.12 arm, so the flattening and the re-IP compose cleanly (one substitutes VALUES, the other substitutes SHAPE) rather than colliding.
  • Attribution discipline for the change-set (Phase 4's job, flagged here so it isn't lost): every diff in the rebuilt opentofu/ tree should be traceable to EITHER "this line's value changed because of D-143" OR "this line/module/step exists or doesn't because of container-elim" -- not both folded into one undifferentiated rewrite. A rewritten Phase-2 runbook that silently also renumbers octets (or vice versa) would make a future revert-one- axis-not-the-other impossible to reason about. Concretely: the module RENAME/RESTRUCTURE (e.g., module.vvr1_dc0 disappearing, module.vr1_dc0_client appearing) is container-elim; the VALUES inside surviving modules changing from 10.12.x to 10.13.x is D-143. A resource that is BOTH new AND carries a 10.13 literal (e.g., the client VM's transit IP) is fine to create once, but its commit/changelog framing should name both governing changes, not blur them into "the redeploy."
  • D-143 item 5 (revoke dc0-substrate credentials before redeploy) interacts directly with the container-elim's credential-residency migration (pass0-admin-report.md row 8 / Section 6 item 6): the OLD credentials being revoked are resident on the (about to be eliminated) vvr1-dc0; the NEW credentials being minted for the rebuild are resident on vr1-dc0-client. This is naturally sequenced (revoke old -> destroy old host -> build new host -> mint new credential) but it means D-143 item 5 and the container-elim's SEC-028/ SEC-029 re-pointing are the SAME step wearing two decision-labels -- call it out as one action justified by both D-NNNs when it's executed, not two separate ones.

4. Teardown of the CURRENT (Model-B, 10.12) live checkpoint -- order

This is the FIRST action of the redeploy (dc0 is already at the confirmed FULL-deployment checkpoint per the operator's pivot memory; dc1 is held). Per the teardown runbook's own discipline (Section 1 above, still valid for tearing down the CURRENT Model-B shape -- the runbook doesn't need to be rewritten to tear down what it already describes correctly):

  1. Path M first, per DC with a live model -- tear down the juju MODEL(s) before touching substrate (dc-dc-teardown-rollback.md Path M, :188-392). This is the D-143 item-5 credential-revoke's natural anchor point too (revoke, then destroy).
  2. D-143 item 5 -- revoke the dc0-substrate credentials (folded into or immediately after step 1, per Section 3 above).
  3. Path C, if a controller needs to come down with the model (only if the controller itself is being retired, not just the model) -- :394-596.
  4. Path B substrate teardown, ordered INNER then OUTER, per DC -- :914-957: from voffice1, tofu destroy each opentofu/vr1-dcN-substrate/ root; THEN, on vcloud, tofu destroy the outer root's vvr1_dc0/vvr1_dc1/vr1_dcN_uplink/vr1_dcN_storage modules. Step 2's MAAS census (:635-747) runs FIRST, per DC, before any destroy -- this is unaffected by container-elim (still the load-bearing "attribute every power_type=virsh record" gate).
  5. Mesh legs -- destroy ONLY if the whole VR1 layer (both DCs) is going away together (:960-995); a checkpoint-then-redeploy that keeps the SAME two DCs (new IPs, new shape, same DCs) should almost certainly PRESERVE the mesh triangle and simply let the flat rebuild re-target it -- destroying and recreating the mesh legs is extra churn with no benefit unless the mesh module ITSELF needs to change shape for the flat topology (UNKNOWN pending Phase 2/W2.1's tofu-module design -- the mesh legs are NOT named as changing in pass0-admin- report.md's "persists" list, Sec 1.3, so the working assumption is they survive; confirm at Phase 2, don't destroy speculatively).
  6. Only after 1-5 converge (Step 5's untargeted tofu plan gate, :894-911, showing zero unexpected drift) does the rebuild begin -- against the Option-1 flat module design, consuming D-143's new NetBox/lib-net.sh literals per Section 3's sequencing.

This order is UNCHANGED by container-elim -- it is the teardown runbook's existing Path M -> C -> B ordering, applied to what is CURRENTLY built (Model-B, 10.12). Container-elim only changes what gets BUILT next (Section 2), not the order in which the current thing comes down.


5. Open items this pass surfaces (not resolved here -- feed to Phase 2/4)

  1. Root topology: one merged root per DC, or a shared outer + per-DC root split retained minus the containment seam? Section 1/2.1 above illustrate BOTH as plausible; Phase 2/W2.1 (OpenTofu module design) is where this gets decided, not this planning pass. This document's tofu destroy illustrations are DELIBERATELY marked illustrative for that reason.
  2. The new teardown-primitive script (module-scoped group-destroy / virsh destroy loop) does not exist yet -- it is a NEW tested artifact this pass identifies as owed, to be built and harnessed per repo discipline (CLAUDE.md "Delivery") once the module design lands.
  3. D-128's Plane-1/Plane-2 split is written entirely around the two-root shape (docs/design-decisions.md:5354-5364). Under Option 1 there is no more "Plane 2 = the INNER tofu root run from voffice1" -- Plane 2 shrinks to MAAS/NetBox only (tofu is now entirely Plane 1, vcloud). This is a D-128 amendment this pass's Phase 4 [ARCH] framing should fold in alongside the D-123 container-elim ruling itself -- flagged here because it was found while reading phase2/phase4's execution-host tables, not because W1.1 is ruling on it.
  4. Artifact-service / rack-controller-remainder / D-131-forwarder placement remains OPEN (pass0-admin-report.md Section 6 item 3) and DIRECTLY determines the SSH-jump-target edit in Section 2.2 above and the maas-vm-host re-homing in Section 2.1's Step-D row. This pass's findings are written generically ("client VM OR maas-01") precisely because that placement is not yet ruled -- do not let a later pass silently pick one without updating both citations here.

6. Verification note

Every path:line cite above was read directly this session from runbooks/dc-dc-teardown- rollback.md, runbooks/dc-dc-phase0-vcloud-prep.md through phase6-designate-cos-magnum.md, runbooks/dc-dc-office1-service-reip.md, opentofu/main.tf (module list), and docs/design-decisions.md (D-128, D-143). No value in this document is inferred from a prior session's summary or from memory -- where a placement or a module name is not yet knowable it is marked UNKNOWN with what resolves it, per hard rule 2.