How It All Fits Together
Current state, target topology, ownership boundaries, control services, storage, and build sequence for the two-site AORXI private cloud.
AORXI is designed as two independent private-cloud sites joined by routed WireGuard. Each site keeps its own WAN edge, Layer 2 fabric, Proxmox quorum, storage, and local recovery path. Site A is the active build; Site B remains a parked design.
Read the State Before the Target
As of 2026-07-26, the working environment is still the Site A bootstrap island. The final architecture is approved and documented, but most of it is not yet deployment evidence.
| Area | Observed or approved state |
|---|---|
| Site A bootstrap network | Live UCG Max, XG 6 PoE, and U7 Pro XGS on 192.168.0.0/23 |
| Site A Proxmox | Live four hosts on temporary addresses; no sa-pve cluster yet |
| Site A edge VMs | Live sa-fw-01, sa-uos-01, and sa-bao-01 on the bootstrap network |
| Site A final LAN | Approved target OPNsense-routed 10.10.x, three-switch UniFi L2 RSTP fabric; not production |
| Site A campaign | A0 evidence must be re-verified; A3–A8 migration gates and A9–A11 platform gates remain pending |
| Site B | Parked no build has started |
| Cross-site services | WireGuard, PBS replication, cross-site DNS, and OpenBao transit auto-unseal remain planned because Site B is absent |
Target State Is Not Live State
Final VLANs, switch profiles, port assignments, clusters, storage services, DNS replication, and Kubernetes/OpenShift remain target state until their gates are executed and recorded. The current addresses and next actions are maintained on the Current Build State page.
The End-to-End Shape
The diagram shows the approved end state. Site A reaches it without rebuilding the LAN during the Internet handoff: the entire final LAN is commissioned behind OPNsense while the UCG temporarily supplies the firewall's WAN.
Site A: Bootstrap, Commissioning, Then Final WAN
The WAN-only A8 handoff happens after every host, service, IPMI interface, AP, SSID, and client passes on its final network. Rollback restores the UCG upstream path; it does not readdress the LAN or move endpoints back to the flat network. After the stability window, the UCG Max and XG6 are powered down and retained as labeled rollback equipment.
During commissioning, the XG6 remains exclusively on the UCG side. Its p4 copper lead services one host or BMC at a time; p5/p6 stay disconnected. No XG10 ever connects to UCG Max or XG6. A3 adopts the switches on final VLAN 10 and starts the target as a two-DAC tree: sw1 p11 ↔ sw2 p11 and sw1 p12 ↔ sw3 p12. A6 adds sw2 p12 ↔ sw3 p11 only after RSTP profiles and priorities are verified.
The final fabric is an RSTP triangle: sa-sw-01 p11 ↔ sa-sw-02 p11,
sa-sw-02 p12 ↔ sa-sw-03 p11, and sa-sw-03 p12 ↔ sa-sw-01 p12.
These three 10 Gb SFP+ links provide switch-link redundancy only. They do not
provide stacking, MLAG, LACP, router HA, or a replacement for sa-fw-01.
RSTP priorities are 4096, 8192, and 12288 for sa-sw-01, sa-sw-02, and
sa-sw-03 respectively. sa-ap-01 terminates on sa-sw-03 p6 with 10 Gb
RJ45 and PoE++.
Site B: Separate Edge and Retained User Branch
Site B keeps the USG Pro user-side branch and its intentional double NAT on VLAN 253. Infrastructure stays directly behind OPNsense and the Netgear L2 core; the UniFi access switch does not carry the forbidden infrastructure VLANs. This is approved design, not deployed state.
Between Sites: Routed Services, Never a Shared Failure Domain
The planned WireGuard transit is 10.255.0.0/24: Site A uses 10.255.0.1,
Site B uses 10.255.0.2, and OPNsense routes 10.10.0.0/16 ↔
10.20.0.0/16. It will carry selected management, DNS replication, PBS
replication, UniFi adoption traffic, monitoring, and OpenBao unseal traffic.
Nothing Stateful Stretches Across the WAN
Proxmox clusters, Corosync, Ceph, OpenBao Raft, and Layer 2 segments remain site-local. WireGuard carries routed packets only. Cross-site continuity uses backups, snapshots, application replication, and GitOps—not stretched quorum or storage.
What Owns Each Layer
Explicit ownership prevents two systems from trying to control the same resource.
| Layer | Site A | Site B | Boundary |
|---|---|---|---|
| WAN, NAT, VPN, stateful policy | sa-fw-01 (OPNsense) | sb-fw-01 (OPNsense) | Each firewall is pinned to its local E200; no HA migration |
| Routed VLAN gateways | OPNsense owns every routed .1 | OPNsense owns routed gateways, including VLAN 253 transit | Switches do not route |
| Client DHCP | OPNsense on VLANs 100/110/120 | OPNsense per the Site B plan | No switch DHCP scopes |
| Switching | sa-sw-01/02/03 L2 RSTP fabric | sb-sw-01 Netgear L2 core; sb-sw-02 access | No stretched L2 |
| Virtualization | Four-node sa-pve target | Six-node sb-pve target | One Proxmox cluster per site |
| Primary storage | ZFS mirror vdevs on sa-stor-01 | Five-node Ceph, replication size 3 | Storage stays site-local |
| Backups | PBS-A local backup target | PBS-B local backup target | Cross-site sync later uses routed VLAN 90 over WireGuard |
| UniFi control | sa-uos-01 controls all Site A switches/APs | sb-sw-02 adopts later over WireGuard; USG Pro stays self-managed | UOS is management-plane only; forwarding survives controller loss |
| Runtime secrets | sa-bao-01 | sb-bao-01 target | One OpenBao instance per site; no stretched Raft |
| Internal DNS | sa-dns-01 primary + sa-dns-02 secondary | sb-dns-01/02 secondaries | AXFR crosses WireGuard; sites answer locally from their copies |
| Kubernetes/OpenShift | Planned after A10 | Planned after Site B foundation | Clusters and machine networks stay site-local |
OPNsense Is the Site A Stateful Boundary
Every Site A target endpoint attaches to a final 10.10.x network behind
OPNsense. The switches have no production SVI, DHCP, static-route, or default-
gateway role. Proxmox, storage, Kubernetes/OpenShift, APs, and clients never
attach directly to the UCG LAN.
Physical Hosts and Site Roles
Site A concentrates management and durable services. Site B concentrates distributed storage and worker-heavy compute.
| Site | Host | Hardware | Role |
|---|---|---|---|
| Site A | sa-edge-01 | Supermicro SYS-E200-8D | Proxmox + pinned sa-fw-01; also hosts sa-uos-01 and sa-bao-01 |
| Site A | sa-cmp-01 | ThinkPad P51 + Intel X550-T2 | Proxmox worker / CI |
| Site A | sa-cmp-02 | ThinkPad P52 + Intel X550-T2 | Proxmox worker / GPU / AI |
| Site A | sa-stor-01 | Supermicro 5049A-T + XL710/X710-class T4 | ZFS, PBS-A, DNS, monitoring, databases |
| Site B | sb-edge-01 | Supermicro SYS-E200-8D | Proxmox + pinned sb-fw-01; planned sb-bao-01 |
| Site B | sb-cmp-01/02 | SYS-5019D-4C-FN8TP | Ceph MON/MGR + Kubernetes control-plane candidates |
| Site B | sb-cmp-03/04/05 | SYS-5018D-FN4T | Ceph OSD + high-core Kubernetes workers |
The E200s reserve capacity for routing and light control services. DNS helpers,
the UniFi controller, OpenBao, a small reverse proxy, and monitoring agents fit;
heavy databases, Ceph OSDs, storage-heavy VMs, and heavy Kubernetes workers do
not. sa-edge-01 remains a deliberate single point of failure for Site A
routing and its colocated control services.
The Network Planes
Both sites reuse the same VLAN IDs where the function is shared. Site A uses
10.10.x.0; Site B uses 10.20.x.0. The exceptions are the Site B-only VLAN
253 legacy transit and the Site A-only VLAN 999 native sink.
| VLAN | Purpose | Site A | Site B | Routing rule |
|---|---|---|---|---|
| 10 | Network Mgmt / IPMI | 10.10.10.0/24 | 10.20.10.0/24 | OPNsense gateway; never expose IPMI to WAN |
| 20 | Proxmox Management | 10.10.20.0/24 | 10.20.20.0/24 | OPNsense gateway |
| 25 | Corosync heartbeat | 10.10.25.0/24 | 10.20.25.0/24 | No gateway site-local only |
| 30 | VM Services | 10.10.30.0/24 | 10.20.30.0/24 | OPNsense gateway |
| 40 | Kubernetes Nodes | 10.10.40.0/22 | 10.20.40.0/22 | OPNsense gateway |
| 50 | K8s LB / VIPs | 10.10.50.0/24 | 10.20.50.0/24 | OPNsense gateway |
| 60 | Storage / Ceph public | 10.10.60.0/24 | 10.20.60.0/24 | No gateway direct client attachment |
| 65 | Ceph cluster | reserved, not carried | 10.20.65.0/24 | No gateway never route to VLAN 60 |
| 70 | DMZ | 10.10.70.0/24 | 10.20.70.0/24 | OPNsense gateway and stateful policy |
| 80 | Monitoring | 10.10.80.0/24 | 10.20.80.0/24 | OPNsense gateway |
| 90 | Backup / Replication | 10.10.90.0/24 | 10.20.90.0/24 | Routed for PBS and snapshot replication |
| 100 | Lab / Trusted Client | 10.10.100.0/22 | 10.20.100.0/22 | OPNsense gateway; Site A DHCP |
| 110 | IoT | 10.10.110.0/24 | 10.20.110.0/24 | OPNsense gateway; restricted policy |
| 120 | Guest WiFi | 10.10.120.0/24 | 10.20.120.0/24 | OPNsense gateway; Internet-only policy target |
| 253 | UniFi WAN transit | absent; 10.10.253.0/24 reserved | 10.20.253.0/24 | Site B OPNsense .1 → USG Pro WAN .2 |
| 4040 | Retired UniFi L3 transit | not configured | not used | No interface or subnet |
| 999 | Native sink / quarantine | no subnet | not used | No IP, gateway, DHCP, or client workload |
On every routed /24, .1 is OPNsense, .2–.9 is network infrastructure,
.10–.39 is physical hosts, .40–.49 is infrastructure VMs, .50–.199 is
DHCP or static services, and .200–.254 is VIP space. Proxmox hosts hold L3
addresses only on infrastructure VLANs they terminate: 10, 20, 25, 60, 65,
and 90. Guest and VM VLANs are bridged without a host IP.
Edge Services and Startup Dependencies
sa-edge-01 carries the minimum services needed to establish and manage the
Site A control plane.
| VM | Live state | Final placement | Relationship |
|---|---|---|---|
sa-fw-01 | Provisioned and baseline-configured on the bootstrap LAN | .1 on routed VLANs 10/20/30/40/50/70/80/90/100/110/120 | Starts first; owns WAN, routing, DHCP, NAT, firewall, and future WireGuard |
sa-uos-01 | Provisioned and first-run configured | 10.10.10.40 on VLAN 10 | Manages sa-sw-01/02/03 and sa-ap-01; Site B UniFi access gear adopts later over WireGuard |
sa-bao-01 | Initialized, unsealed, and seeded | 10.10.30.40 on VLAN 30 | Supplies runtime secrets; currently requires manual 3-of-5 Shamir unseal after reboot |
The controller is not in the forwarding path: adopted switches and APs continue to forward if UOS is down, while configuration and telemetry pause. OpenBao is also outside the runtime packet path; a sealed instance blocks normal config lookups, not an already-applied OPNsense configuration. OPNsense must boot before OpenBao because the future cross-site tunnel becomes the transit-unseal path.
Protect the Edge and Management Plane
sa-fw-01 and sb-fw-01 stay pinned to their local E200s. IPMI remains on
VLAN 10 behind management policy and is never Internet-facing. A bad edge or
firewall change is recovered through local console/IPMI and exported configs,
not automatic VM migration.
Provisioning, Configuration, and Secrets
The repository separates object creation from in-system configuration.
| Concern | Owner | Repository surface |
|---|---|---|
| Proxmox API objects, VMs, cloud images, host firewall | Pulumi | platform/, opnsense/provision/, unifi/provision/, openbao/provision/, shared core/ |
| Proxmox host OS hardening | Ansible | baseline/ |
| OPNsense, UOS, and OpenBao application configuration | Ansible over HTTP APIs | opnsense/config/, unifi/config/, openbao/config/ |
| Everyday safety wrappers | Root Makefile | Pulumi preview remains separate from apply; Ansible check precedes apply and apply requires LIMIT |
| Proxmox host firewall | Pulumi only | Default off; enable post-cluster, one host at a time, with console/IPMI available |
Ansible does not manage a competing host firewall. One manager per layer avoids ruleset drift and lockout.
Secrets follow a two-tier bootstrap boundary:
| Tier | Store | Purpose |
|---|---|---|
| 0 | Gitignored repo-root .env.local plus password manager | Pulumi passphrase, vault password, fallback Proxmox credentials, OpenBao AppRole bootstrap, and recovery material |
| 1 | OpenBao KV v2 mount homelab | Runtime OPNsense, UniFi, and Pulumi/Proxmox credentials with per-consumer read-only AppRoles |
Consumers read OpenBao first and fall back to encrypted Ansible vault files or
.env.local. Unset BAO_ADDR selects pure fallback mode. Tier 0 never moves
into OpenBao: the secrets needed to rebuild and unseal OpenBao cannot depend on
OpenBao itself. Each site eventually runs an independent single-node Raft
instance; snapshots, not Raft quorum, cross sites.
Storage, Backup, DNS, and Certificates
Storage and Recovery
- Site A:
sa-stor-01targets 8–12 Samsung SM863 1.92 TB SSDs in ZFS mirror vdevs. PBS-A uses10.10.30.20for management and10.10.90.40for backup data. - Site B: five compute nodes target 20–30 local Ceph OSDs with replication
size 3. VLAN 60 is the client-facing public network; VLAN 65 is isolated OSD
replication/backfill. Ceph is pinned to the Proxmox
tentacleno-subscription repository and excluded from unattended upgrades. - Cross-site DR: each site backs up locally first. PBS replication and OpenBao Raft snapshots later cross WireGuard on the routed backup path.
No Stretched Storage
Ceph stays entirely at Site B. VLANs 60 and 65 have no gateway, and traffic is never routed between them. Cross-site recovery uses PBS sync and snapshots, not live storage replication.
Naming and Certificates
OPNsense Unbound provides the initial resolver. The A10 target adds four
Technitium DNS VMs on VLAN 30: sa-dns-01 (10.10.30.10) is primary,
sa-dns-02 (10.10.30.11) is the local secondary, and sb-dns-01/02
(10.20.30.10/.11) are read-only secondaries over WireGuard. Site B serves its
last replicated zones locally if the tunnel fails.
The internal zone is core.aorxi.io; the public domain is aorxi.io on
Cloudflare. Certificates use Let's Encrypt with Cloudflare DNS-01 for
*.core.aorxi.io and *.aorxi.io. No private CA is required.
Kubernetes and OpenShift Fit Above the Foundation
Kubernetes/OpenShift comes after stable routing, storage, backups, and DNS.
VLAN 40 carries node networks (10.10.40.0/22, 10.20.40.0/22); VLAN 50
carries API, ingress, and LoadBalancer VIPs. The planned stack is Cilium in
overlay mode, MetalLB, cert-manager, external-dns, ArgoCD, and ingress-nginx or
Traefik.
Site A OpenShift machine networks begin at 10.10.128.0/22, then
10.10.132.0/22 and 10.10.136.0/22, with 10.10.144.0/20 reserved for
expansion. They deliberately avoid trusted-client VLAN 100
(10.10.100.0/22). Site B retains 10.20.100.0/22, 10.20.104.0/22,
10.20.108.0/22, and 10.20.112.0/21 expansion.
Pod and service CIDRs remain separate from physical LAN and VPN ranges.
Examples include pod blocks 10.128.0.0/14, 10.132.0.0/14, and service
blocks such as 172.30.0.0/16 within 172.16.0.0/12. 172.32.x.x is not
RFC 1918 and must not be used.
The Active Site A Campaign
The A0–A11 plan is the execution spine. Each gate produces cable and port evidence, previews/check-mode output, positive and negative reachability tests, and fresh configuration exports where relevant.
| Gate | Outcome | State on 2026-07-26 |
|---|---|---|
| D0 | Accept the complete clean-slate design | approved design |
| A0 | Re-verify UCG/XG6/AP backups, labels, inventory, and rollback paths | re-verification required |
| A1 | Four hosts built through the one-at-a-time XG6 p4 service lead; baseline verified | working foundation exists |
| A2 | Edge bridges and sa-fw-01/sa-uos-01/sa-bao-01 staged | edge VMs live; gate evidence should be retained |
| A3 | Dual-home UOS onto VLAN 10, then build and adopt all three XG10s as a final-addressed loop-free target tree without UCG/XG6 connectivity | pending |
| A4 | Commission and prove the remaining OPNsense-owned VLANs and policy behind UCG-fed WAN | pending |
| A5 | Prove UOS through the target, retire its bootstrap vNIC, then move OpenBao, host management, and IPMI to final addresses | pending |
| A6 | Add the third DAC, close the RSTP triangle, and pass one-link failures | pending |
| A7 | Move AP, SSIDs, wired clients, and wireless clients to final VLANs | pending |
| A8 | Freeze the LAN and move only the WAN feed from UCG to the ONT | pending |
| A9 | Configure Corosync VLAN 25 and create four-node sa-pve on sa-stor-01 | planned |
| A10 | Build ZFS, PBS-A, Technitium DNS, and monitoring | planned |
| A11 | Deploy Kubernetes/OpenShift after all foundation gates pass | planned |
Design Invariants and Accepted Limits
The Short Non-Negotiable List
- One Proxmox cluster per site; Corosync never crosses WAN or WireGuard.
- No stretched Ceph, OpenBao Raft, or Layer 2.
- OPNsense owns Site A routing and stays pinned to
sa-edge-01. - Site A VLANs 25 and 60 have no gateway; VLAN 65 is reserved and not carried; VLANs 253/4040 are absent; VLAN 999 is an unrouted native sink.
- IPMI is isolated on VLAN 10 and never exposed to the Internet.
- The
sa-stor-01AQC107/atlanticinterface carries no management or Corosync traffic; use it only for non-critical data or leave it unused.
Known tradeoffs remain visible: sa-edge-01 is a routing/control-plane single
point of failure; Site A Corosync shares links on some hosts while Site B uses
dedicated links; the ThinkPads have no IPMI; sa-bao-01 needs manual Shamir
unseal until Site B exists; and the UCG creates accepted temporary double NAT
during Site A commissioning. None of these weak points changes the ownership
or failure-domain rules above.