Hub and spoke landing zone on OVHcloud Public Cloud
Deploy a production-ready hub and spoke landing zone on OVHcloud Public Cloud using a single shared vRack with transit routing: HA firewall, governance, private networking, IaC automation, and lifecycle management.
Objective
This guide walks cloud architects through deploying a hub and spoke landing zone on OVHcloud Public Cloud using a single shared vRack with transit routing โ the simplest hub and spoke topology available on OVHcloud.
It covers project layout, governance, private network topology, network security, centralised logging, billing control, and spoke lifecycle management.
This guide explains how to build a production-ready hub and spoke landing zone on OVHcloud Public Cloud, from initial architecture decisions to ongoing operations.
Building a hub and spoke landing zone is a complex, multi-team undertaking. OVHcloud Professional Services can assist with architecture design review, assisted deployment, and operational readiness assessment.
Requirements
- An active OVHcloud account with API credentials (Application Key, Application Secret, Consumer Key)
- Public Cloud access with sufficient quota to create projects, a vRack, instances, and a Floating IP
- OpenTofu โฅ 1.11.4 installed on your workstation (HashiCorp Terraform is not compatible โ native state encryption is an OpenTofu-specific feature)
- Basic understanding of networking concepts (CIDR, VLAN, routing)
- Familiarity with the OVHcloud Terraform provider
OVHcloud Control Panel Access
- Direct link:
Instructions
1. Landing zone and hub and spoke architecture
A landing zone is a pre-configured cloud environment that provides the security, governance, networking, identity, and auditability foundations your workloads need before deployment. Without one, organisations face configuration drift, security gaps, uncontrolled costs, and limited auditability.
OVHcloud supports several landing zone topologies (flat, segmented, hub and spoke). For a full conceptual overview, see Understanding Landing Zones. This guide focuses on hub and spoke with a single shared vRack, where all projects share one private network backbone and route all traffic through a centralised HA firewall at the hub.
In this topology, each component has a distinct role:
Running example โ OrbitalEdge SAS: The concrete examples throughout this guide are drawn from OrbitalEdge, a fictitious 45-person scale-up based in Paris that develops an edge computing platform for satellite constellation operators (LEO fleets, environmental monitoring). They deploy four spokes in the EU-WEST-PAR region: constellation-dev, constellation-prod, signalvault-dev, and signalvault-prod. Their four teams interact with the landing zone as follows:
The full OrbitalEdge IaC configuration โ including terraform.tfvars for all four spokes โ is available under examples/orbital-edge in the hub-and-spoke-public-cloud repository.
Plan the full address space before deploying any infrastructure. The transit VLAN (200) and subnet (192.168.10.0/24) are fixed and shared across all projects:
All projects share the same vRack (L2 domain). VLAN IDs must be globally unique across all projects โ two projects using the same VLAN ID on the same vRack will collide. IP CIDRs must also be globally unique for routing. The one exception is the transit VLAN 200 (192.168.10.0/24): all projects reference it intentionally, each spoke using a distinct IP within it.
Looking for a ready-made IaC implementation? The open-source hub-and-spoke-public-cloud project provides a complete OpenTofu reference for this architecture under deployments/mono-vrack-lan-transit.
2. Key Benefits and Regions
2.1 Why hub and spoke?
Isolation model: East-west isolation between spokes is enforced entirely by OPNsense firewall rules at the hub. All spoke Neutron routers are visible on the shared transit VLAN โ inter-spoke communication is blocked by hub rules, not by L2 separation. For workloads that require cryptographic separation between spokes (e.g. PCI-DSS, classified environments), consider the multi-vrack-ipsec variant (one vRack per project, IPsec tunnels between hub and spokes).
2.2 Available regions
OVHcloud Public Cloud regions span Europe, North America, and Asia-Pacific. The orbital-edge example deploys in EU-WEST-PAR (Paris).
For the current complete list see the OVHcloud Public Cloud regions availability page.
Your region choice affects:
- Data localisation: for GDPR/NIS2 compliance, choose French or European continental regions.
- Instance flavour availability: not all flavours (
b3-16,b3-64) are available in every region โ verify before provisioning. - Latency: co-locate hub and all spoke projects in the same region for minimal routing latency across the transit VLAN.
3. Governance and Access Management
For a detailed walkthrough of OVHcloud IAM, see Securing & Structuring Public Cloud Projects.
3.1 Account security baseline
Before creating any project:
- Enable Two-Factor Authentication (2FA) on the root account: Control Panel > top-right initials >
Security. - Add a backup email address (must differ from the primary).
- Set a strong, unique password (see Password management guide).
3.2 Local users, groups, and RBAC policies
IAM policies are provisioned automatically by OpenTofu (iam.tf) per spoke deployment. Define the groups below and assign scoped policies to each Public Cloud project:
In the OrbitalEdge example, iam.tf automatically creates and assigns policies on each tofu apply. However, the local user accounts themselves must be created in the OVHcloud Manager before the first tofu apply โ they are a prerequisite, not an output: Alice and Baptiste (Platform team), Camille (FleetOS), Driss (SignalVault), and Elena (CISO).
To create a policy:
- Go to
IAM>Policies>Create a policy. - Name it following the
{resource}-ROor{resource}-RWpattern. - Assign the target group, product type (
Public Cloud project), resource, and permission.
3.3 Identity federation (optional)
Connect your corporate identity provider to OVHcloud IAM so users authenticate with their existing credentials:
Groups defined in your IdP are included in the SAML assertion and mapped to OVHcloud IAM groups.
3.4 Service accounts for IaC
Create a dedicated service account (not your personal account) to authenticate your IaC tool against the OVHcloud API. Grant it the minimum permissions required:
- Create and manage Public Cloud projects
- Create and manage vRack, attach projects
- Create OpenStack users within projects
Generate API credentials using the OVHcloud API token generator. Store the Application Key, Application Secret, and Consumer Key securely โ never in source control.
3.5 OpenStack users per project
OpenStack users are provisioned automatically by OpenTofu (users.tf), one per project. At minimum, create users with the following role split:
This separation prevents runtime workloads from accidentally modifying network or security configurations. In the orbital-edge example, OpenTofu stores the generated OpenStack credentials in the Terraform state; Alice retrieves them post-apply and stores them in HashiCorp Vault.
3.6 IaC credentials governance
Never commit files containing real credentials (variable files, .env, secrets) to version control.
Recommended patterns:
- Local development: keep variable files outside the repository or in a
.gitignored path. - CI/CD pipelines: inject credentials as environment variables via your pipeline secrets store (HashiCorp Vault, GitHub Secrets, GitLab CI Variables, etc.). In the orbital-edge example, Alice injects all
TF_VAR_*secrets from HashiCorp Vault before eachtofu apply. - Remote state: use an S31-compatible backend (OVHcloud Object Storage) with server-side encryption or client-side state encryption enabled. Isolate each deployment (hub, each spoke) in its own state file. OpenTofu โฅ 1.11.4 supports native state encryption with PBKDF2 + AES-GCM.
4. Deploy the Architecture
The steps below describe what to provision and why. In the orbital-edge example, all steps in this section are automated by OpenTofu: Day-1 (landing-zone/tofu apply) deploys the hub project, vRack, and OPNsense HA pair; Day-2 (spoke-template/tofu apply) provisions each spoke and configures hub routing automatically. See the hub-and-spoke-public-cloud open-source project (deployments/mono-vrack-lan-transit).
The steps in sections 4.1โ4.4 describe what
landing-zone/tofu applyautomates. Follow them if you prefer to deploy without IaC.
4.1 Create Public Cloud projects
Create at least two projects to start:
- Hub project โ hosts the OPNsense HA firewall cluster, Internet gateway, and shared services.
- Spoke-QA project โ an initial spoke for validating the topology before going to production.
Use a consistent naming convention to enable governance scoping, billing isolation, and automation โ for example: {domain}_{application}_{environment} (e.g. infra_hub_prod, finance_invoicing_qa). Each project gets its own billing boundary, access scope, and OpenStack credential set. OrbitalEdge uses hubonevrack-orb, constellation-dev, constellation-prod, signalvault-dev, and signalvault-prod โ all created automatically by OpenTofu.
After creating a project, OVHcloud requires a short propagation window (typically 30 seconds) before a vRack can be successfully attached. The IaC reference implementation includes time_sleep resources to handle this automatically.
4.2 Create the shared vRack and attach projects
A vRack is an OVHcloud private layer-2 backbone. In this architecture, one shared vRack is used for all projects โ hub and all spokes attach to the same vRack. This is what makes transit routing possible: the hub LAN and each spoke's transit network interface share the same VLAN 200 segment across the vRack.
Attachment order:
- Create one vRack for the entire landing zone.
- Attach the hub project to the vRack.
- Attach the spoke-QA project to the same vRack.
- Plan and record the full VLAN and CIDR table before creating any networks (see section 1). VLAN assignments are effectively irreversible โ changing them later requires reprovisioning all affected networks.
All projects share the same L2 domain. Never assign the same VLAN ID to two different projects. The only exception is VLAN 200 (transit), which all projects reference by design.
4.3 Hub HA firewall cluster and transit network
The hub OPNsense HA cluster is the sole firewall and routing choke-point for the entire landing zone. Provision it before any spoke. In the orbital-edge example, the entire hub โ networks, OPNsense HA pair, Floating IP, CARP VIPs, and HASYNC โ is deployed automatically by landing-zone/tofu apply (takes 5โ8 minutes).
-
3 private networks in the hub project, each on a distinct VLAN:
- WAN network (VLAN 100, 10.1.0.0/24) โ connects to the OVH Gateway for Internet egress/NAT.
- Transit/LAN network (VLAN 200, 192.168.10.0/24) โ the shared transit subnet. Every spoke Neutron router connects here. The hub OPNsense LAN CARP VIP (192.168.10.99) is the default gateway for all spokes.
- HASYNC network (VLAN 199, 10.0.254.0/30) โ dedicated to OPNsense HA state replication (CARP/pfsync); no other traffic on this VLAN.
-
OVH Gateway on the WAN network โ provides NAT and Internet routing for all outbound spoke traffic. See the Private Network with Gateway guide for setup steps.
-
Two OPNsense instances (primary and secondary) โ deploy from a cloud-ready image (e.g. OPNsense 26.1-cloudready). Recommended minimum sizing:
b3-16(4 vCPUs / 16 GB RAM). Use an anti-affinity server group to place primary and secondary on different hypervisors. Attach each instance to all three networks (WAN, Transit/LAN, HASYNC). -
Floating IP โ attach a public Floating IP to the WAN CARP VIP port. This is the sole public-facing IP for the entire landing zone: management access (SSH, OPNsense web UI on port 8443) and Internet egress for all spokes.
-
CARP VIPs โ configure two CARP Virtual IPs:
- WAN CARP VIP (e.g. 10.1.0.99) โ NAT source address for all outbound traffic.
- LAN CARP VIP (192.168.10.99) โ default gateway for every spoke Neutron router. This address must remain stable across failovers.
-
HASYNC and pfsync โ configure OPNsense HA synchronisation over the HASYNC interface so firewall state, rules, and configuration replicate automatically between primary and secondary.
OpenStack port security must be disabled on vRack-backed networks that carry CARP traffic. Port security filters gratuitous ARPs, which CARP relies on for VIP failover. Disable it at the network level:
Security is then enforced entirely by OPNsense โ ensure your firewall rules are in place before disabling port security.
4.4 Security baseline
Apply the following controls before exposing the hub to any traffic:
OpenStack security group on the hub WAN port โ restrict inbound access to the Floating IP:
All other inbound traffic is blocked at the OpenStack layer before reaching OPNsense.
SSH keys โ inject the operator SSH public key into all instances via cloud-init at provisioning time. Do not use password-based SSH.
OPNsense admin password โ use a strong, randomly generated password. Pass it as a bcrypt hash to cloud-init so the plaintext never appears in instance metadata. Store it in your secrets manager, not in source control.
IaC state files โ store state in an S3-compatible backend (OVHcloud Object Storage) with server-side encryption. State files may contain sensitive outputs (Floating IPs, API keys, passwords).
4.5 Record hub parameters for spoke onboarding
Once the hub is deployed, record these values โ every spoke will need them:
Store these in your team's shared secrets manager or secure runbook.
5. Logging and Monitoring
5.1 Centralised log collection
Configure OPNsense to forward syslog to OVHcloud Logs Data Platform (LDP):
- In OPNsense:
System>Log Files>Remote Logging. - Set the syslog target to your LDP input endpoint (UDP/TCP 514 or GELF).
- Enable logging for firewall rules and system events.
Follow the LDP quick start guide to provision your log stream and Kibana/OpenSearch dashboard.
OVHcloud managed services (Managed Databases, Managed Kubernetes) also support native log forwarding to LDP โ see Forwarding logs from OVHcloud products to Logs Data Platform.
5.2 Metrics and alerting
Recommended alerting thresholds:
6. Onboarding a New Spoke
Each spoke is an independent Public Cloud project attached to the shared vRack. It has its own billing boundary, OpenStack users, and IAM policies. No OPNsense cluster, Floating IP, or OVH Gateway is needed โ all traffic routes via the hub.
6.1 Prerequisites
Before adding a spoke, confirm you have:
- Hub deployed and HTTPS-accessible at
https://<hub_floating_ip>:8443 - Hub LAN CARP VIP (192.168.10.99) and hub LAN CIDR (192.168.10.0/24) noted (section 4.5)
- Hub vRack service name noted (section 4.5)
- Hub OPNsense API credentials available
- A unique transit router IP assigned within the transit subnet, outside the hub DHCP pool (.100โ.200) โ e.g. 192.168.10.10 for the first spoke, 192.168.10.20 for the second
- Unique VLAN IDs and CIDRs assigned for all spoke LAN networks (section 1)
6.2 Provision spoke resources
In the OrbitalEdge example,
constellation-devis the first spoke: transit router IP192.168.10.10, VLAN 300 (10.30.0.0/24) for its Kubernetes workload tier. Thesignalvault-devspoke adds two LAN networks โ app (VLAN 310,10.31.0.0/24) and data (VLAN 311,10.31.1.0/24) โ with a single Neutron router at192.168.10.11. All steps below are automated byspoke-template/tofu apply; Alice fills in the VLAN/CIDR values interraform.tfvarsand runstofu apply(~3 minutes per spoke).
The following steps describe what
spoke-template/tofu applyautomates. Follow them if you prefer to onboard spokes without IaC.
Perform these steps in order, waiting for each OVHcloud API operation to complete before proceeding:
- Create a Public Cloud project for the spoke (follow naming convention from section 4.1) โ e.g.
constellation-dev. - Attach the spoke project to the shared vRack using the hub vRack service name (e.g.
pn-123456). Wait for the propagation delay (30 seconds) before creating networks. - Create the transit network in the spoke project: VLAN 200, CIDR 192.168.10.0/24, DHCP disabled, no gateway. This exposes the hub transit segment inside the spoke's OpenStack context so the Neutron router can attach to it.
- Create spoke LAN networks โ one network per workload tier (app, db, etc.), each on a unique VLAN with DHCP enabled โ e.g. VLAN 300,
10.30.0.0/24. - Create an OpenStack Neutron router:
- Attach the transit network with a fixed IP at the spoke's transit router IP (e.g.
192.168.10.10forconstellation-dev). - Attach each spoke LAN subnet as an internal interface.
- Set the default route:
0.0.0.0/0via the hub LAN CARP VIP (192.168.10.99).
- Attach the transit network with a fixed IP at the spoke's transit router IP (e.g.
- Create OpenStack users (IaC operator and runtime operator) for the spoke project โ created automatically by OpenTofu (
users.tf) in the orbital-edge example.
6.3 Configure hub routing
The following steps describe what
spoke-template/tofu applyautomates for hub-side routing. Follow them if you are not using IaC.
Once the spoke Neutron router is up, register it on the hub OPNsense via the REST API:
Add a gateway pointing to the spoke's transit router IP:
Add a static route for each spoke LAN CIDR:
If you use the IaC reference implementation (spoke-template), all hub-side routing steps are automated via the restapi Terraform provider and run as part of tofu apply.
6.4 Verify connectivity
SSH to the hub's Floating IP and confirm the spoke is reachable:
6.5 ProxyJump for SSH access to spoke instances
Spoke instances have no direct public IP. Access them through the hub Floating IP:
For audited access at scale, deploy OVHcloud Bastion on a dedicated instance in the hub project.
6.6 Onboarding checklist
- VLAN IDs and CIDRs recorded in network design document and assigned uniquely
- Transit router IP assigned โ unique within 192.168.10.0/24, outside DHCP pool (.100โ.200)
- Spoke project created and attached to shared vRack
- Transit network (VLAN 200, DHCP disabled) created in spoke project
- Spoke LAN networks created with DHCP enabled
- Neutron router created with transit fixed IP and LAN interfaces
- Default route on Neutron router set to hub LAN CARP VIP (192.168.10.99)
- Hub gateway (
Spoke<N>TransitGW) added via OPNsense API and reconfigured - Hub static routes added for each spoke LAN CIDR and reconfigured
- Spoke LAN reachable from hub via ping
- IAM policies created for spoke project (developer + SRE groups)
- OpenStack users provisioned and credentials distributed to spoke team
- Logging forwarded to LDP
- SSH ProxyJump or Bastion access configured and tested
7. Lifecycle โ Scale, Evolve, Delete
7.1 Scaling โ adding spokes
Repeat the onboarding process (section 6) for each new spoke. Assign a unique transit router IP and unique VLAN IDs from your network plan. Each spoke is independent โ adding one has no impact on existing spokes, and only adds a gateway and static routes on the hub OPNsense.
As the number of spokes grows, monitor hub OPNsense CPU and throughput. The hub handles all north-south and east-west traffic for every spoke โ right-size it accordingly (b3-16 for most deployments, b3-64 for high-traffic environments or many spokes).
When OrbitalEdge needed a fifth spoke for historical data archival (telemetry-archive-prod), the process took less than 30 minutes: reserve transit IP 192.168.10.30, assign VLAN 510 (10.51.0.0/24) for the app tier and VLAN 511 (10.51.1.0/24) for the data tier, copy the spoke template directory, fill in terraform.tfvars, and run tofu apply. The four existing spokes were unaffected โ no hub downtime, no firewall restart.
7.2 Removing a spoke
The following steps describe what
tofu destroydoes when decommissioning a spoke. Follow them if you are not using IaC.
Decommission in reverse order of provisioning:
- Remove hub-side routing โ on the hub OPNsense, delete the static routes for the spoke LAN CIDRs and the spoke gateway:
System>Routes: delete spoke LAN routes, then clickApply changes.System>Gateways: delete the spoke transit gateway.- Or via API:
POST /routes/routes/delroute/{id}thenPOST /routes/routes/reconfigure, andPOST /routing/settings/del_gateway/{id}thenPOST /routing/settings/reconfigure.
- Destroy spoke resources โ delete the Neutron router interfaces and router, LAN networks, transit network, and Public Cloud project. If using IaC, run a destroy operation scoped to the spoke's state.
- Verify on hub โ confirm no orphaned objects remain:
System>Routes: spoke LAN routes gone.System>Gateways: spoke gateway gone.
- Update network design document โ release the VLAN IDs and transit IP for reuse.
7.3 Updating OPNsense
OPNsense updates (security patches, minor releases) follow a CARP failover procedure:
- Ensure CARP is operational:
Interfaces>Virtual IPs>Status. - Set the secondary node to CARP maintenance mode (demote to BACKUP).
- Update the secondary:
System>Firmware>Updates. - Reboot secondary; verify it rejoins CARP as BACKUP.
- Perform a controlled failover: promote secondary to MASTER temporarily.
- Update and reboot primary.
- Restore original MASTER/BACKUP roles.
During steps 3โ4, all traffic traverses the primary node. All spoke workloads depend on the hub for Internet access and inter-spoke routing โ schedule maintenance during low-traffic windows.
7.4 Quarterly review checklist
8. Billing, Cost Centres, and Carbon
8.1 Per-project cost isolation
OVHcloud Public Cloud billing is scoped per project. Each spoke project gives you a clean cost boundary for a team, application, or business unit.
Export cost data via the OVHcloud API:
See Public Cloud billing guide for full API details and CSV export options.
8.2 Tagging strategy
Tag all resources consistently at provisioning time, for example:
Tags enable cost allocation reports, automated cleanup policies, and compliance audits.
8.3 Budget alerts
Set up spending thresholds in the OVHcloud Control Panel:
- Go to
Billing>Budget alerts. - Define a monthly threshold per project.
- Configure email or webhook notification when 80% and 100% of the budget is reached.
8.4 Carbon footprint
OVHcloud data centres in Europe (GRA, SBG, WAW, LIM) have among the lowest Power Usage Effectiveness (PUE) ratings in the industry, with renewable energy commitments in several sites.
To minimise your carbon impact:
- Prefer European regions with declared renewable energy sourcing.
- Right-size the hub:
b3-16is sufficient for most deployments โ avoid over-provisioning. - Use Object Storage lifecycle policies to transition cold logs to Infrequent Access and expire temporary data.
- Decommission unused spokes rather than leaving idle infrastructure running.
9. Conclusion
The single vRack hub and spoke model on OVHcloud Public Cloud gives organisations a production-ready, auditable, and scalable landing zone. A centralised OPNsense HA firewall controls all outbound and inter-spoke traffic. Spoke projects require only standard OpenStack Neutron routers โ no per-spoke firewall cluster, no IPsec tunnels โ making this the simplest hub and spoke topology available on OVHcloud.
Deploying and operating this architecture requires solid cloud and network skills, including OVHcloud vRack and VLAN management, OPNsense HA cluster operation, and Infrastructure as Code practices. Teams new to these technologies are strongly encouraged to engage OVHcloud Professional Services for design review, assisted deployment, or an operational readiness assessment before going to production.
Request a quote from OVHcloud Professional Services
Go further
- Understanding Landing Zones
- Architecture Reference โ Building a Landing Zone with OVHcloud Public Cloud
- Best Practices for securing & structuring OVHcloud Public Cloud Projects
- How to use Terraform with OVHcloud Public Cloud
- Configuring vRack for Public Cloud using OVHcloud APIv6
- Getting started with Logs Data Platform
Join our community of users.
1: S3 is a trademark of Amazon Technologies, Inc. OVHcloud's service is not sponsored by, endorsed by, or otherwise affiliated with Amazon Technologies, Inc.