Status: DESIGN / PLAN. Originating design for the virtual regional two-DC test environment (VR1: DC1, DC2, Office1 headend). PROPOSED decisions live in docs/design-decisions.md as D-100..D-110. No live mutation is authorized from this document; it is the plan the phased runbooks execute against.
Governing constraint: minimize delta to Roosevelt (the future bare-metal multi-DC production site). Every virtual choice maps to a defensible real one; the one deliberate exception is tagged in the shim register (Section 9).
Ground truth / copy point: seeded from openstack-caracal-ipv4 at commit 8813efc into openstack-caracal-dc-dc (verified). Six-plane values are scripts/lib-net.sh (CIDR-keyed); fabrics / VLANs are docs/maas-as-built-reference.md; NetBox (vcloud-local) is the IPAM apex for all address literals.
| Plane | v1/DC0 v4 (DC1 inherits) | VR1 family | Note |
|---|---|---|---|
| provider-public | 10.12.4.0/22 | v4 + GUA | public API VIPs + FIP/ext_net; GUA via owned edge |
| metal-admin | 10.12.8.0/22 | v4 only | operator / MAAS / PXE / admin API; DC-local |
| metal-internal | 10.12.12.0/22 (VID 103) | v4 + ULA | API endpoints dual-stack; MySQL/RabbitMQ stay v4 |
| data-tenant | 10.12.16.0/22 | ULA only | geneve overlay; tenant GUA delegated separately |
| storage | 10.12.32.0/22 | ULA only | Ceph public; ms_bind_ipv6 |
| replication | 10.12.36.0/22 | ULA only | Ceph cluster; cross-DC leg rides this (ULA) |
DC2 mirrors this structure on a distinct, non-overlapping supernet. All literals (ULA /48, per-DC GUA carve from the /36, DC2 v4 supernet) are NetBox-assigned -- not hardcoded. PXE and datastore east-west are the two deliberate v4-retained points.
Single vcloud host: ~256 vCPU / 1 TiB RAM / 10 TiB disk, dedicated to VR1. CPU and RAM are abundant; disk is the binding constraint (two Ceph clusters + per-DC backup/mirror + images). Phase-0 gates:
nested module param; Intel vs AMD differs). Verify guest virtualization is exposed to the DC node VMs.Each phase has a single goal, a verify-before-mutate gate, and owning D-entries. Phases run in order; a phase is not entered until the prior gate passes. Per operating discipline, the per-phase runbooks (later deliverables) carry the command-level steps with harnesses; this document is the plan they execute.
Goal: turn the bare vcloud host into a substrate the Office1 headend can deploy from. Build: nested KVM enabled; libvirt storage pools + thin-provisioning; the dark-fiber and per-site ISP-edge virtual networks; the six per-DC plane segments (as virtual networks); the MTU plan set on the underlay. Gate: nested KVM verified; disk budget computed and the Ceph size decision recorded; measured MTU recorded; virtual networks present and isolated as designed. Owns: D-100 (fabric), D-101 (MTU -- folds in former D-102 per the 2026-07-09 operator ruling), Section 3 gates.
Goal: stand up the operator's deployment headend first, before any DC. Build: MAAS region controller; OpenTofu; NetBox (vcloud-local, importer extended for multi-DC + dual-stack); GitBucket (vcloud-local mirror); Tailscale front door (Office1 only). Gate: MAAS region reachable; NetBox authoritative and populated (planes, per-DC v4, ULA/GUA carve); GitBucket serving; OpenTofu can reach the vcloud host libvirt; Tailscale access confirmed to Office1 only. Owns: D-103 (Office1 service VMs are OpenTofu-created), D-107 (headend is not a core-service provider).
Goal: from Office1, script each DC's "physical" layer into existence. Build: per DC, OpenTofu creates the node-VM libvirt domains (SHIM -- Section 9), the DC's plane networks, and the DC's OPNsense edge; registers the DC libvirt host to that DC's MAAS rack controller as a virsh VM-host. Gate: MAAS rack controller per DC up; MAAS discovers the OpenTofu-created node VMs; edge routing + simulated ISP uplink up; netem parameters applied and measured. Owns: D-103 (seam), D-100 (edges).
Goal: bring the discovered node VMs to a deployed OS, ready for Juju. Build: per DC, MAAS commissions and deploys the node VMs; provider NIC left RAW (br-ex discipline, D-100); the VLAN-103 metal-internal bridge stack pre-built by MAAS. Gate: nodes deployed; the six planes present per node with correct fabrics/VLANs; provider NIC raw; PXE (v4) working; per-DC mirror reachable from nodes; NTP from edge working. Owns: D-103, D-100 (br-ex), D-107 (mirror + NTP).
Goal: a running independent OpenStack cloud per DC. Build: per DC, bootstrap the single-unit Juju controller in-DC; deploy the Caracal bundle; Vault init with per-DC independent root, issuing v4 + IPv6-SAN certs; the family matrix applied (ULA on data/storage/replication, dual-stack metal-internal API, GUA provider). Gate: preflight.sh PASS before add-model; post-deploy cloud-assert.sh --capture per DC; controller backup taken and stored; Ceph-over-v6 and geneve-over-v6 verified. Owns: D-104 (controllers), D-109 (Vault), D-101 (families).
Goal: prove Tier-A recoverability, one-way first, then two-way. Build: replication-plane peering (ULA); radosgw multisite zonegroup (two DCs as zones); rbd-mirror for the Glance pool; cinder-backup to the replicated object store; consistency groups where needed. Run the failover / failback drill (Section 8). Stage one-way, then enable two-way after a clean drill. Gate: one-way drill clean (RTO/RPO measured); then two-way; controller restore drill (D-104) exercised; RTO recorded as a measured output, not an SLA. Owns: D-108 (replication), D-104 (control-plane backup/restore in the drill).
Goal: complete the service set in both DCs. Build: per DC, Designate (designate-bind) with per-DC zones + A/AAAA per the D-008 bootstrap order; COS observability; Magnum / CAPI with in-cloud single-homed capi-mgmt (domain-setup re-run per D-046). Gate: Designate resolving A + AAAA; FQDN-SAN certs valid (D-019/D-021 root cause closed); COS scraping; a CAPI workload cluster comes up per DC. Owns: D-106 (Designate), D-105 (CAPI/COS).
tc netem on the inter-DC and site-uplink virtual segments. Default lean: same-metro dark fiber (low single-digit ms, jumbo-capable). Parameters (latency / jitter / loss / rate) are a Phase-0 knob and are recorded per drill so RTO/RPO actuals are attributable to a known link profile. Re-tune to the confirmed Roosevelt inter-DC profile when known.
VR1 rehearses the full developed IPv6 plan because the simulated OPNsense edge is ours (the D-015 upstream-router gate does not apply): internal IPv6-only ULA (data / storage / replication / Octavia lb-mgmt / P2P), internal dual-stack ULA on metal-internal API endpoints, and external GUA (provider public VIPs, native v6 ext_net, tenant delegation). Ceph-over-v6 (ms_bind_ipv6), geneve-over-v6 MTU, and native v6 tenant routing are the high-value Roosevelt proofs. Phase-A internal-three goes straight to v6-only (lean; dual-then-flip is the conservative fallback if Phase-0 verification is not clean).
Failover (DC1 lost, recover at DC2):
Failback (DC1 recovered) -- split-brain-safe for two-way:
The only steps with NO Roosevelt analog (tag them clearly; do not treat as reusable production IaC):
tc netem WAN simulation (D-100). In Roosevelt the inter-DC link is real fiber; netem is replaced by the physical link. The route + bandwidth budget it stands in for IS real.All six items below were ruled by the operator on 2026-07-09; see the referenced D-NNN entries in docs/design-decisions.md for the authoritative recorded text. D-100 through D-110 are now ADOPTED (D-102 MERGED into D-101; D-109 confirmed standalone) -- Stage 0 of docs/dc-dc-deployment-workflow.md is CLEARED.
docs/dc-dc-D100-D110.append.md (from its first ## D-100 line) to the end of docs/design-decisions.md, then remove the fragment file.bash scripts/ledger-scan.sh; confirm D next-free = 111 and the machine-derived ledger block regenerates cleanly. Do not hand-edit the machine-derived block.docs/session-ledger.md recording this deliverable (design doc + D-100..D-110 PROPOSED).bash scripts/repo-lint.sh for ASCII/LF/format (ignore any next-free noise above 099 -- known band bug; ledger-scan is the next-free authority).