Prep/handoff for the Stage-3 Phase-2 DC0 build (runbooks/dc-dc-phase2-tofu-dc-substrate.md, Model B two-root). Written 2026-07-16 at the outer-apply gate. A FRESH session starts the deployment from here. Nothing has been applied -- the outer tofu apply is the first mutation and is operator-gated. vr1-dc1 is HELD (no ruled addressing; see below), DC0 only.
STATUS 2026-07-17: PREP COMPLETE -- DC0 IS DEPLOY-READY. Final gate re-checked: opentofu-validate clean (both roots + 12 modules), the four
vr1_dc0_rack_*+vr1_dc0_ssh_pubkey_pathtfvars in place,creds-audit vr1-dc0CLEAN, gauntlet ALL GREEN (65), repo-lint 0-fail. Per-env-key (D-126 option a) DONE; netem = placeholder (deploy-time, Step 11). The ONLY remaining items are NOT prep: (1) the final bookend restart -- OS patch + reboot of vcloud + voffice1 + office1-opnsense, done together as the boundary into the new session (voffice1 is load-bearing like vcloud -- it hosts netbox/MAAS + the only netbox path, so it defers WITH vcloud, not mid-prep); (2) fresh-session start = re-verify the plan (state drifts after a reboot -- VMs stop) + open a logged shell + gated outer apply. Decoupled hygiene (NetBox D-124/edge-WAN import; the Stage-3 record sweep) is OPTIONAL and can run anytime -- it does NOT gate the deploy (no netbox provider in the tree).
ssh voffice1 / office1-netbox / office1-tailscale / office1-opnsense all EXERCISED live (ProxyJump via ~/.ssh/config.d/vr1-sites, one-key office1 env ~/vr1-office1-creds/office1_svc_ed25519). Committed+pushed (bc2be83).~/vr1-dc0-creds/ + ~/vr1-dc1-creds/ (0700, empty); creds-manifests/vr1-dc{0,1}.manifest declare each DC's dedicated per-env key.opentofu/d124-rack.auto.tfvars (LOCAL/gitignored) holds the four D-124-ruled vr1_dc0_rack_* values (10.12.8.2, 172.31.0.2, /30, 172.31.0.1).vr1-dc0 planes + 3 mesh links + vr1-dc0-pool/office1-pool active.opentofu-validate -- root + 12 modules clean (both roots tofu validate).tofu -chdir=opentofu plan => 5 add / 2 in-place / 6 destroy, decomposed and verified:
autostart false->true -- an update-in-place (verified: NOT replacement; replacement would destroy the live host/edge). These COLLAPSE to 0-change once the bookend sets them autostart=true live before the fresh-session apply.vvr1_dc0 containment VM (425984 MiB = 416 GiB / 108 vCPU -- full-fleet D-121/R-3 sizing, expose_nested_virt) + disk/seed/cloudinit; vr1_dc0_uplink (D-125 simulated-ISP NAT).vr1-dc0 plane networks -- INTENDED Model B relocation from vcloud (outer) to inside vvr1-dc0 (inner root recreates them, vr1-dc0-substrate/main.tf:28). All six are EMPTY (0 leases, 0 attached domains). No live/consumed infra touched.A fresh session MUST re-run the plan and re-confirm 5-add/(0-or-2)-change/6-destroy-empty (autostart in-place collapses to 0 post-bookend) before apply (live state can drift; verify, don't assume).
tofu apply)vvr1-dc0 = option (a) dedicated dc0 key (operator ruling). DONE: minted ~/vr1-dc0-creds/vr1-dc0_svc_ed25519 (600/644, creds-audit vr1-dc0 CLEAN); added variable "vr1_dc0_ssh_pubkey_path"; vvr1-dc0 cloud-init now installs the dc0 pubkey (voffice1 keeps office1's key); tfvar set. Re-validated + re-planned -> outer plan UNCHANGED (5/0/6, create-only content). Remaining for the inner apply: the inner root's qemu+ssh to vvr1-dc0 must use the dc0 PRIVATE key -- wire an ssh alias/-i ~/vr1-dc0-creds/vr1-dc0_svc_ed25519 AFTER the outer apply boots vvr1-dc0 (its transit IP is knowable then; D-126 DC ssh-config rows are deferred to that point).bunzip2 -- required by scripts/opnsense-prep-image.sh. Under Model B that prep runs ON vvr1-dc0 (bootstrap step B), so install it there (apt) post-boot; NOT needed for the outer apply. (Absent on vcloud today -- fine unless any prep is run vcloud-side.)maas-vm-host register, Model B step D): maas_api_url/maas_api_key are deliberately unset (empirically revealed at Step 8/9); maas_api_key is a SECRET via TF_VAR_maas_api_key. Confirm the Office1 MAAS region is reachable and export the key before Step 9. Steps A-C (outer apply -> bootstrap -> inner node/plane/edge) do NOT need MAAS.netem-link mechanism with a placeholder value at Step 11; the "final" latency/loss ruling (D-100 gap #11) is DEFERRED. Non-blocking for the outer apply.vvr1-dc0 boots + sized + nested-KVM on (the rack IS vvr1-dc0).site-headend-install.sh --role rack --host-nodes --check PASS incl. SEC-010 (transit FORWARD-drop, DC-LOCAL); prep OPNsense base ON vvr1-dc0.WAN_IF/LAN_IF on the real OPNsense; MAAS zone/pool + power_address.ssh office1-netbox)netbox/d124-transit-seed.py (NEW) seeded role transit
172.31.0.0/24 container; dc-rack-mgmt-import placed 172.31.0.0/30 (vr1-dc0) + 10.12.8.2/22 (rack). Ran on the apex host, token server-side, sandbox-only.dc-edge-wan-import created 172.30.2.0/24 + 172.30.3.0/24 (edge). (Also recovered the apex: netbox-docker was down; brought up + restart: unless-stopped added.)docs/design-decisions.md: D-122 MAAS-bullet + site-down wording, D-107 node-artifacts scoping + DR-claim honesty, D-121 Option-C disk record (the optc-calc.py "reproducible" reference is to an ABSENT script -- fix or commit the calc; whole-host math lives in scripts/dc-dc-whole-host-budget.py), D-115 status-line vs ledger-scan, SEC-011 reconsider (downgraded to OBSERVATION).vr1-dc1 -- HELD (do not attempt)No ruled dc1 transit/rack addressing (the 172.31.0.0/24 transit supernet is dc0-scoped), and no vr1_dc1_rack_* variables or dc1 substrate exist. dc1 needs its own transit-prefix ruling + variable
git pull ; bash scripts/repo-lint.sh (0 fail; 1 legacy WARN) ; bash scripts/run-tests-all.sh.docs/session-ledger.md + bash scripts/ledger-scan.sh -- reconcile in-flight state.runbooks/dc-dc-phase2-tofu-dc-substrate.md (Model B reshape section, ~line 144).bash scripts/run-logged.sh dc0-deploy.| Step | Action | Type |
|---|---|---|
| A | outer tofu apply -- vvr1-dc0 (416G/108) + vr1_dc0_uplink; relocate 6 empty planes |
MUTATION (gated) |
| B | bootstrap vvr1-dc0: site-headend-install.sh --role rack --host-nodes + SEC-010; prep OPNsense base there |
MUTATION (gated) |
| C | inner tofu apply (vr1-dc0-substrate, qemu+ssh): 9 node VMs + 6 planes + OPNsense edge INSIDE vvr1-dc0 |
MUTATION (gated) |
| D | maas-vm-host register vvr1-dc0 inner virsh -> Office1 region; MAAS discovers nodes |
MUTATION (gated, needs C2.3) |
| E | netem on the vcloud mesh bridges (outer) | MUTATION (gated, needs C2.4) |
| GATE | D-125 foreign-MAC egress isolation test; depth-4 boot; SEC-010 packet-drop | verify |
EXIT -> Stage 4 (per-DC), once dc1 clears its own gate.