Back to blog

March 24, 2026 • 6 min read

Hub-and-Spoke Architecture with Zero Trust Networking

How I simplified networking, access control, and cost with a hub-and-spoke model.

Introduction#

Most teams start with per-environment networks; Dev, QA, and Prod each with their own NAT, firewall, DNS, and load balancers. This approach is simple at first but quickly becomes costly, inconsistent, and difficult to secure.

In this post, I walk through how to adopt a hub-and-spoke network architecture secured with Cloudflare Zero Trust (ZTN). I cover why teams choose this model, how traffic flows, and the security benefits in production.

This is a write-up of a session I ran in 2025.


The Problem: Per-Environment Networking#

Each environment duplicating infrastructure looks like this:

  • NAT, firewall, load balancer, DNS repeated in every environment
  • Multiple ingress/egress points to manage
  • Firewall policies scattered and inconsistent
  • Logs and monitoring fragmented
  • Higher costs and configuration drift risks
Traditional per-environment networking diagram showing duplicated resources across Dev, QA, and Prod
Figure 1: Traditional per-environment networking - duplicated resources across Dev, QA, and Prod.

What seems easy for a small setup becomes a bottleneck at scale.


The Solution: Hub-and-Spoke Architecture#

In a hub-and-spoke model:

  • The hub contains shared services: NAT, firewall, DNS, load balancer.
  • Spokes are isolated environments (Dev, QA, Prod) that stay private.
  • All ingress and egress flows through the hub.

Benefits:

  • Centralized firewall and NAT management
  • Uniform policies
  • Reduced cost (one NAT, one firewall instead of many)
  • Easier audits and observability
Diagram of a hub centralising shared networking and security while spokes remain private
Figure 2: Hub centralises shared networking and security, while spokes remain private and isolated.

Traffic flows#

Per-environment model#

  • Public traffic hits environment-specific load balancers.
  • Applications egress through separate NATs.
  • Each environment manages its own firewall rules.
Diagram of per-environment traffic flow with multiple load balancers and NAT gateways
Figure 3: Per-environment traffic flow - multiple load balancers and NAT gateways per environment.

Hub-and-spoke model#

  • Public traffic flows → hub load balancer → spokes.
  • Outbound traffic flows → spokes → hub NAT → internet.
  • Developers and admins authenticate via Zero Trust before reaching any spoke.
Diagram of hub-and-spoke traffic flow with a single entry and exit point through the hub
Figure 4: Hub-and-spoke traffic flow - single entry and exit point through the hub.

Cloudflare Zero Trust#

Cloudflare Zero Trust replaces traditional VPN-based access with identity and context-aware policies:

  • No public IPs needed for internal services
  • Access authenticated per user, device, and policy
  • Granular access control instead of broad VPN tunnels
Diagram showing Cloudflare Zero Trust acting as the identity-aware access layer
Figure 5: Cloudflare Zero Trust acts as the identity-aware access layer, replacing public IPs and VPNs.

With Cloudflare ZTN, neither the hub nor the spokes need public exposure. Access flows through Cloudflare’s global edge, authenticated per user/device/policy.

In practice, this gave me tighter access control and much cleaner audit trails than a shared VPN model.


Deploying the Cloudflare connector#

Run the cloudflared daemon on a hub VM:

sudo cloudflared service install <token>

Then apply a strict firewall rule so cloudflared can only reach Cloudflare endpoints on TCP/UDP 7844.

From there, internal spokes no longer need public IPs. Developer and admin access goes through Cloudflare, while production traffic can continue through the external load balancer.

{
  name        = "allow-cloudflared-to-endpoints"
  description = "Allow cloudflared egress to the cloudflare endpoints"
  action      = "allow"
  direction   = "EGRESS"
  priority    = 501
  dest_fqdns = [
    "region1.v2.argotunnel.com",
    "region2.v2.argotunnel.com",
    "cftunnel.com",
    "h2.cftunnel.com",
    "quic.cftunnel.com"
  ]
  layer4_configs = [
    {
      ip_protocol = "tcp"
      ports       = ["7844"]
    },
    {
      ip_protocol = "udp"
      ports       = ["7844"]
    }
  ]
}

See the Cloudflare Docs – Tunnel with Firewall.


Final architecture#

The final state looks like this:

  • Hub centralises NAT, firewall, and load balancers
  • Spokes are fully private
  • Cloudflare Tunnel provides secure developer/admin access
  • End users reach production apps only via the external load balancer
Diagram of the final hub-and-spoke architecture secured with Cloudflare Zero Trust
Figure 6: Final architecture - unified hub handling all ingress and egress, secured with Cloudflare Zero Trust.

This pattern isolates environments, simplifies operations, and eliminates public exposure.

You trade a bit of routing complexity for a much cleaner security and operations model.


Industry references#

Google Cloud#

GCP reference architecture showing Fortinet firewalls securing the hub
Figure 7: GCP reference architecture - Fortinet firewalls securing the hub, similar to large-scale environments.

Google Cloud publishes a reference hub-and-spoke model with Fortinet appliances protecting the hub.

See the Google Cloud – Fortinet Reference Architecture.

Microsoft Azure#

Azure reference architecture showing Azure Firewalls securing the hub
Figure 8: Azure reference architecture - Azure Firewalls securing the hub, similar to large-scale environments.

Azure publishes a reference hub-and-spoke model with Azure Firewall appliances, Bastion, and VPN gateways protecting the hub.

See the Hub-spoke network topology in Azure.


Tradeoffs#

No design is free:

  • Routing is more complex than per-environment
  • Hub is a critical dependency → must be highly available
  • Steeper learning curve for teams
  • Centralization means changes affect all environments

Key considerations#

When deploying hub-and-spoke, plan for:

  • IP address space (avoid overlaps)
  • Non-transitive peering (spoke-to-spoke must go via hub, or use Shared VPC / PSC / NCC)
  • Scaling limits (peering, firewall throughput, cloudflared sizing)
  • High availability (multi-zone, multi-region hub design)
Diagram of non-transitive connectivity before redesign where spokes cannot communicate directly
Figure 9: Non-transitive connectivity before redesign - spokes cannot communicate directly.
Diagram showing non-transitive connectivity resolved via hub routing with spoke-to-spoke traffic flowing through the hub
Figure 10: Non-transitive connectivity resolved via hub routing - spoke-to-spoke traffic flows through hub.

Hands-on resources#

I published Terraform examples that show three ways to deploy Cloudflare Tunnels in hub-and-spoke:

  • Full IaC with Kubernetes (complete automation)
  • Manual + Kubernetes (use existing tunnel, deploy cloudflared only)
  • Manual VM on GCP (run cloudflared on Compute Engine)

Cloudflare Zero Trust Terraform templates (GitHub)


Further Reading & Resources#

Closing note#

Hub-and-spoke with Zero Trust is not magic, but it is practical. If your environments are growing and your network policy is getting noisy, this pattern is worth piloting.