Hub-Spoke Topology: Enterprise Network Architecture

The scalable pattern enterprises use to centralize shared services and connect dozens of VNets
🟑 Intermediate ⏱ 20 Minutes πŸ“˜ AZ-104 Β· Module 04
Why This Matters

Imagine managing 50 separate office buildings, each with its own security guard, firewall, and reception desk. Nightmare, right? Hub-spoke is how Azure organizations scale. One central hub handles shared services (firewall, VPN, DNS) and spokes connect to it like branches to a tree. Every major enterprise uses this pattern. Understanding it unlocks most exam scenarios.

Before You Start

PrerequisitesVNets & Subnets, Network Security Groups, Routing Fundamentals, VNet Peering, VPN & ExpressRoute
Time to understand20 minutes
Difficulty🟑 Intermediate (combines multiple networking concepts)
What you'll learnHub-spoke architecture, when to use it, how to implement at scale

The Simple Idea

What Is Hub-Spoke?

Hub-Spoke = A network architecture where one central VNet (hub) holds shared services, and multiple VNets (spokes) peer to it β€” spokes don't talk directly to each other, they route through the hub.

What Goes in the Hub?

Hub VNet contains shared infrastructure:

  • VPN Gateway (on-premises connection)
  • ExpressRoute Gateway (dedicated circuit)
  • Azure Firewall (centralized inspection)
  • DNS Resolver (shared DNS)
  • Network NVA (network appliance)
Airline Network (Hub-Spoke): Old Model (Messy): NYC ↔ LA ↔ Chicago ↔ Denver ↔ Boston └─ Every city connected to every other city └─ Too many routes, hard to manage, expensive βœ— Hub-Spoke Model (Clean): β”Œβ”€β”€β”€ NYC (Spoke) β”‚ Dallas (Hub) ─── LA (Spoke) β”‚ β”œβ”€ Chicago (Spoke) β”‚ └─ Boston (Spoke) All flights go through Dallas hub β”œβ”€ Easier to manage βœ“ β”œβ”€ Centralized security/customs βœ“ β”œβ”€ Economies of scale βœ“ └─ Spokes don't need direct routes βœ“

How Hub-Spoke Works

Architecture Diagram

On-Premises (192.168.0.0/16) β”‚ β”‚ VPN / ExpressRoute ↓ Hub VNet (10.0.0.0/16) β”œβ”€β”€ GatewaySubnet (10.0.1.0/24) β€” VPN/ExpressRoute Gateway β”œβ”€β”€ AzureFirewallSubnet (10.0.2.0/24) β€” Firewall (centralized inspection) β”œβ”€β”€ SharedServicesSubnet (10.0.3.0/24) β€” DNS, shared resources └── ManagementSubnet (10.0.4.0/24) β€” Admin tools β†— Peering β†– / \ Spoke-Prod Spoke-Dev Spoke-Test (10.1.0.0/16) (10.2.0.0/16) (10.3.0.0/16) β”œβ”€ App tier β”œβ”€ App tier β”œβ”€ App tier └─ DB tier └─ DB tier └─ DB tier Peering Features: β”œβ”€ Hub β†’ Spoke: "Allow gateway transit" βœ“ β”œβ”€ Spoke β†’ Hub: "Use remote gateway" βœ“ └─ Result: Spokes use hub's VPN to reach on-premises βœ“

Step 1: Create Hub VNet

Hub VNet: 10.0.0.0/16 β”œβ”€β”€ GatewaySubnet: 10.0.1.0/24 β”‚ └─ Used by: VPN Gateway β”œβ”€β”€ AzureFirewallSubnet: 10.0.2.0/24 β”‚ └─ Used by: Azure Firewall β”œβ”€β”€ SharedServicesSubnet: 10.0.3.0/24 β”‚ └─ Used by: DNS, shared apps └── ManagementSubnet: 10.0.4.0/24 └─ Used by: Admin VMs

Step 2: Create Spoke VNets

Spoke-Prod: 10.1.0.0/16 β”œβ”€β”€ WebSubnet: 10.1.1.0/24 β”œβ”€β”€ AppSubnet: 10.1.2.0/24 └── DBSubnet: 10.1.3.0/24 Spoke-Dev: 10.2.0.0/16 β”œβ”€β”€ WebSubnet: 10.2.1.0/24 β”œβ”€β”€ AppSubnet: 10.2.2.0/24 └── DBSubnet: 10.2.3.0/24 Spoke-Test: 10.3.0.0/16 β”œβ”€β”€ WebSubnet: 10.3.1.0/24 β”œβ”€β”€ AppSubnet: 10.3.2.0/24 └── DBSubnet: 10.3.3.0/24 Requirement: No overlapping address spaces βœ“

Step 3: Deploy Gateways in Hub

VPN Gateway in Hub: β”œβ”€β”€ Deployed in GatewaySubnet (10.0.1.0/24) β”œβ”€β”€ Connects to on-premises via Site-to-Site VPN β”œβ”€β”€ Peering option: "Allow gateway transit" ENABLED └─ Result: All spokes can reach on-premises through hub Azure Firewall in Hub: β”œβ”€β”€ Deployed in AzureFirewallSubnet (10.0.2.0/24) β”œβ”€β”€ Private IP: 10.0.2.4 β”œβ”€β”€ All internet traffic from spokes routes through it └─ Result: Centralized inspection, threat detection βœ“

Step 4: Create Peering (Hub ↔ Spokes)

Peering 1: Hub ↔ Spoke-Prod β”œβ”€β”€ Hub side: "Allow gateway transit" = YES β”œβ”€β”€ Spoke side: "Use remote gateway" = YES β”œβ”€β”€ Traffic forwarding: ENABLED └─ Result: Spoke-Prod routes through hub βœ“ Peering 2 & 3: Hub ↔ Spoke-Dev, Hub ↔ Spoke-Test └─ Same pattern, both connected βœ“ Note: Spokes are NOT directly peered to each other βœ—

Step 5: Configure Routing

In Hub VNet, create User-Defined Routes: Route Table "HubRoutes": β”œβ”€β”€ 0.0.0.0/0 β†’ Azure Firewall (10.0.2.4) β”‚ └─ All internet traffic through firewall β”œβ”€β”€ 192.168.0.0/16 β†’ VPN Gateway β”‚ └─ On-premises traffic through gateway └── Apply to: All hub subnets In Each Spoke, create User-Defined Routes: Route Table "Prod-Routes": β”œβ”€β”€ 0.0.0.0/0 β†’ Hub Firewall (10.0.2.4) β”‚ └─ Internet traffic via hub firewall β”œβ”€β”€ 192.168.0.0/16 β†’ Hub VPN Gateway β”‚ └─ On-premises via hub gateway β”œβ”€β”€ 10.2.0.0/16 β†’ Hub firewall β”‚ └─ Dev traffic via hub (not direct) β”œβ”€β”€ 10.3.0.0/16 β†’ Hub firewall β”‚ └─ Test traffic via hub (not direct) └── Apply to: All prod subnets (except spokes already peered) Result: β”œβ”€ Prod internal traffic: Direct (10.1.0.0/16) β”œβ”€ Prod β†’ Dev traffic: Through hub firewall βœ“ β”œβ”€ Prod β†’ Internet: Through hub firewall βœ“ └─ Prod β†’ On-prem: Through hub VPN βœ“

Step 6: Apply NSG Rules

Hub Firewall Subnet NSG: β”œβ”€β”€ Allow inbound from all spokes (10.1.0.0/16, 10.2.0.0/16, etc.) β”œβ”€β”€ Allow inbound from on-premises (192.168.0.0/16) β”œβ”€β”€ Allow outbound to internet └─ Result: Firewall can inspect all traffic βœ“ Spoke-Prod App Subnet NSG: β”œβ”€β”€ Allow inbound from Prod Web Subnet (10.1.1.0/24) β”œβ”€β”€ Allow inbound from Hub Firewall (10.0.2.4/32) β”œβ”€β”€ Deny all other inbound └─ Result: App layer only accessible from web tier and hub βœ“ Spoke-Dev App Subnet NSG: β”œβ”€β”€ Allow inbound from Dev Web Subnet (10.2.1.0/24) β”œβ”€β”€ Allow inbound from Hub Firewall (10.0.2.4/32) β”œβ”€β”€ Deny Dev β†’ Prod (traffic filtered at firewall) └─ Result: Dev isolated from prod βœ“

Mental Model: Hub-Spoke as Postal System

Postal Hub-Spoke Network: Central Post Office (Hub) β”œβ”€β”€ Sorting facility β”œβ”€β”€ Border control (customs/inspection) β”œβ”€β”€ International mail gateway └── Shared infrastructure Regional Branches (Spokes) β”œβ”€β”€ Branch 1 (Production) β”œβ”€β”€ Branch 2 (Development) β”œβ”€β”€ Branch 3 (Testing) └── All mail between branches goes through central office Mail Flow: └── Branch1 β†’ Central Hub β†’ Inspection β†’ Forward to Branch2 βœ“ Benefits: β”œβ”€β”€ Central inspection point (security) β”œβ”€β”€ Shared border gateway (cost savings) β”œβ”€β”€ Easy to add new branches └── Scalable architecture βœ“

Worked Example: Real Scenario

The Scenario

TechCorp Enterprise:

  • Headquarters: Dallas data center (192.168.0.0/16)
  • 3 business units: Production, Development, Testing
  • Each needs isolated Azure environment
  • All need access to on-premises data
  • All traffic to internet must be inspected for security

Architecture Design

Hub VNet (10.0.0.0/16) - Dallas region β”œβ”€β”€ GatewaySubnet (10.0.1.0/24) β”‚ └─ VPN Gateway (connects to on-premises) β”œβ”€β”€ AzureFirewallSubnet (10.0.2.0/24) β”‚ └─ Azure Firewall (centralized inspection) β”œβ”€β”€ SharedServicesSubnet (10.0.3.0/24) β”‚ └─ DNS resolver, monitoring agents └── ManagementSubnet (10.0.4.0/24) └─ Admin VM for troubleshooting Spoke-Prod (10.1.0.0/16) - Production β”œβ”€β”€ WebSubnet (10.1.1.0/24) β€” Load balancer, web VMs β”œβ”€β”€ AppSubnet (10.1.2.0/24) β€” App servers └── DBSubnet (10.1.3.0/24) β€” Production databases Spoke-Dev (10.2.0.0/16) - Development β”œβ”€β”€ WebSubnet (10.2.1.0/24) β”œβ”€β”€ AppSubnet (10.2.2.0/24) └── DBSubnet (10.2.3.0/24) Spoke-Test (10.3.0.0/16) - Testing β”œβ”€β”€ WebSubnet (10.3.1.0/24) β”œβ”€β”€ AppSubnet (10.3.2.0/24) └── DBSubnet (10.3.3.0/24)

Step 1: Setup Hub

1. Create Hub VNet (10.0.0.0/16) 2. Create 4 subnets (Gateway, Firewall, SharedServices, Management) 3. Deploy VPN Gateway in GatewaySubnet └─ Configure for on-premises connection 4. Deploy Azure Firewall in AzureFirewallSubnet └─ Assign static public IP 5. Create DNS Resolver in SharedServicesSubnet └─ For hybrid DNS resolution

Step 2: Setup Spokes

1. Create 3 spoke VNets: β”œβ”€ Prod (10.1.0.0/16) β”œβ”€ Dev (10.2.0.0/16) └─ Test (10.3.0.0/16) 2. In each spoke, create 3 subnets: β”œβ”€ Web (Web servers / load balancer) β”œβ”€ App (Application servers) └─ DB (Databases) 3. Verify: No overlapping address spaces βœ“

Step 3: Create Peerings

Peering: Hub ↔ Prod β”œβ”€ Hub setting: "Allow gateway transit" = YES β”œβ”€ Prod setting: "Use remote gateway" = YES β”œβ”€ Traffic forwarding: ENABLED └─ Status: Connected βœ“ Peering: Hub ↔ Dev β”œβ”€ Hub setting: "Allow gateway transit" = YES β”œβ”€ Dev setting: "Use remote gateway" = YES β”œβ”€ Traffic forwarding: ENABLED └─ Status: Connected βœ“ Peering: Hub ↔ Test β”œβ”€ Hub setting: "Allow gateway transit" = YES β”œβ”€ Test setting: "Use remote gateway" = YES β”œβ”€ Traffic forwarding: ENABLED └─ Status: Connected βœ“ NOT Created: Prod ↔ Dev, Prod ↔ Test, Dev ↔ Test └─ Keeps environments isolated βœ“

Step 4: Configure Routing in Hub

DestinationNext HopPurpose
0.0.0.0/0Firewall (10.0.2.4)Internet traffic
192.168.0.0/16VPN GatewayOn-premises

Apply to all hub subnets.

Step 5: Configure Routing in Spokes

DestinationNext HopPurpose
10.0.0.0/16Hub (peering)Hub access (peering, not UDR needed)
10.2.0.0/16Firewall (10.0.2.4)Dev traffic via firewall
10.3.0.0/16Firewall (10.0.2.4)Test traffic via firewall
192.168.0.0/16VPN Gateway (via hub)On-premises via hub
0.0.0.0/0Firewall (10.0.2.4)Internet via firewall

Apply to all prod subnets. Dev and Test get similar routes (swap Prod with Dev/Test as destination).

Step 6: Configure NSGs

Prod WebSubnet NSG

β”œβ”€β”€ Allow inbound on 80, 443 β”‚ from 0.0.0.0/0 (internet) β”œβ”€β”€ Allow inbound on port 8080 β”‚ from App subnet (10.1.2.0/24) └── Deny all other inbound

Prod AppSubnet NSG

β”œβ”€β”€ Allow inbound from Web subnet β”‚ (10.1.1.0/24) β”œβ”€β”€ Allow inbound from Hub Firewall β”‚ (10.0.2.4/32) β”œβ”€β”€ Allow outbound to DB subnet β”‚ (10.1.3.0/24) β”œβ”€β”€ Allow outbound to Firewall β”‚ (10.0.2.4/32) └── Deny all other inbound

Prod DBSubnet NSG

β”œβ”€β”€ Allow inbound port 1433 β”‚ from App subnet (10.1.2.0/24) β”œβ”€β”€ Deny all inbound from other β”‚ spokes (firewall inspects, β”‚ can't bypass) └── Deny internet access (Dev and Test get similar NSGs)

Hub Firewall Subnet NSG

β”œβ”€β”€ Allow inbound from all spokes (10.1.0.0/16, 10.2.0.0/16, 10.3.0.0/16) β”œβ”€β”€ Allow inbound from on-prem (192.168.0.0/16) β”œβ”€β”€ Allow outbound to internet └── Allow outbound to all subnets

Step 7: Test Traffic Flows

Scenario 1: Prod VM to Internet

β”œβ”€ ProdVM (10.1.2.10) β†’ Destination 8.8.8.8 β”œβ”€ Routing: 0.0.0.0/0 β†’ Firewall (10.0.2.4) β”œβ”€ Path: Prod App β†’ Hub Firewall β†’ Internet β”œβ”€ Firewall: Inspect traffic βœ“ └─ Result: Allowed (if rule permits) βœ“

Scenario 2: Prod VM to On-Premises

β”œβ”€ ProdVM (10.1.2.10) β†’ Server (192.168.1.50) β”œβ”€ Routing: 192.168.0.0/16 β†’ VPN Gateway (via hub peering) β”œβ”€ Path: Prod App β†’ Hub VPN Gateway β†’ VPN Tunnel β†’ On-prem β”œβ”€ Gateway: Encrypt/decrypt βœ“ └─ Result: Connected βœ“

Scenario 3: Prod VM to Dev VM

β”œβ”€ ProdVM (10.1.2.10) β†’ DevVM (10.2.2.10) β”œβ”€ Routing: 10.2.0.0/16 β†’ Firewall (10.0.2.4) β”œβ”€ Path: Prod App β†’ Hub Firewall β†’ Dev App β”œβ”€ Firewall: Can block cross-environment traffic βœ“ β”œβ”€ NSG (Dev App): Allows or blocks from firewall └─ Result: Controlled by firewall rules βœ“

Scenario 4: Admin Troubleshooting

β”œβ”€ Admin in Hub Management subnet (10.0.4.10) β”œβ”€ Needs to check Prod DB (10.1.3.20) β”œβ”€ Routing: 10.1.0.0/16 β†’ Peered (direct) β”œβ”€ NSG: Prod DB may or may not allow management IPs └─ Result: Depends on NSG policy βœ“

Common Mistakes (What NOT to Do)

❌ Mistake 1: Peering All Spokes to Each Other

Wrong

Create peerings: β”œβ”€ Hub ↔ Prod β”œβ”€ Hub ↔ Dev β”œβ”€ Prod ↔ Dev (DIRECT PEERING!) β”œβ”€ Prod ↔ Test β”œβ”€ Dev ↔ Test └─ Too many connections to manage βœ— Problems: β”œβ”€ Lost central inspection (Prodβ†’Dev bypasses firewall) β”œβ”€ Hard to scale (add 4th spoke = 3 new peerings) β”œβ”€ Security risk (no firewall filter) └─ Maintenance nightmare βœ—

Fix

Only peer spokes to hub: β”œβ”€ Hub ↔ Prod βœ“ β”œβ”€ Hub ↔ Dev βœ“ β”œβ”€ Hub ↔ Test βœ“ └─ Spokes don't talk directly All spoke-to-spoke traffic routes through firewall βœ“

Why it fails: Defeats the purpose of hub-and-spoke architecture.

❌ Mistake 2: Forgetting Gateway Transit Settings

Wrong

Peering created: Hub ↔ Prod β”œβ”€ "Allow gateway transit": NOT enabled on hub β”œβ”€ "Use remote gateway": Enabled on prod β”œβ”€ Prod VM tries to reach on-premises β”œβ”€ Traffic routes to hub, but hub can't β”‚ forward to VPN β”œβ”€ Result: Connection fails βœ—

Fix

Peering: Hub ↔ Prod β”œβ”€ Hub side: "Allow gateway transit" = YES β”œβ”€ Prod side: "Use remote gateway" = YES β”œβ”€ Both must be set correctly β”œβ”€ Now prod can use hub's VPN βœ“

Why it fails: Both sides of the peering need compatible settings.

❌ Mistake 3: Non-Transitive Routing

Wrong

Assumption: "If Hub ↔ Prod and Hub ↔ Dev are peered, Prod and Dev can talk" Reality: β”œβ”€ Peering is non-transitive β”œβ”€ A ↔ B and B ↔ C doesn't mean β”‚ A ↔ C automatically βœ— β”œβ”€ Prod can reach Hub β”œβ”€ Dev can reach Hub β”œβ”€ But Prodβ†’Dev traffic doesn't β”‚ automatically work └─ Need explicit UDR routing through firewall βœ“

Fix

Configure UDRs in spokes: β”œβ”€ Prod Route Table: 10.2.0.0/16 β†’ Firewall β”œβ”€ Dev Route Table: 10.1.0.0/16 β†’ Firewall β”œβ”€ Now traffic goes: Prod β†’ Firewall β†’ Dev β”œβ”€ Firewall can inspect and allow/block └─ Transitive connectivity achieved βœ“

Why it fails: Peering doesn't transitively connect spokes.

❌ Mistake 4: Overlapping Address Spaces

Wrong

Hub: 10.0.0.0/16 Prod: 10.0.0.0/16 (SAME!) Dev: 10.2.0.0/16 Try to peer: β”œβ”€ Hub ↔ Prod: FAILS (overlapping) βœ— β”œβ”€ Hub ↔ Dev: OK └─ Cannot achieve full hub-spoke βœ—

Fix

Plan CIDR ranges upfront: β”œβ”€ Hub: 10.0.0.0/16 β”œβ”€ Prod: 10.1.0.0/16 βœ“ β”œβ”€ Dev: 10.2.0.0/16 βœ“ β”œβ”€ Test: 10.3.0.0/16 βœ“ β”œβ”€ On-prem: 192.168.0.0/16 └─ All peering works βœ“

Why it fails: Overlapping addresses cause routing ambiguity.

Hub-Spoke Checklist

Planning

β–‘ Identify hub location (central region, on-premises connection point) β–‘ Plan CIDR ranges (hub + all spokes, no overlaps) β–‘ Decide on shared services (VPN, firewall, DNS) β–‘ Document traffic flow policies (who talks to whom)

Hub Setup

β–‘ Create Hub VNet with planned CIDR β–‘ Create GatewaySubnet (for VPN/ExpressRoute) β–‘ Create AzureFirewallSubnet (if using firewall) β–‘ Create SharedServicesSubnet (DNS, shared resources) β–‘ Deploy VPN/ExpressRoute Gateway (if hybrid needed) β–‘ Deploy Azure Firewall (if centralized inspection needed) β–‘ Create Hub Route Table (internet β†’ firewall, on-prem β†’ gateway)

Spoke Setup

β–‘ Create Spoke VNets (non-overlapping CIDR) β–‘ Create subnets (Web, App, DB or similar tiers) β–‘ Create Spoke Route Tables (internet/other-spokes/ on-prem β†’ firewall)

Peering

β–‘ Peer Hub ↔ Spoke-1 └─ Hub: "Allow gateway transit" = YES └─ Spoke-1: "Use remote gateway" = YES β–‘ Peer Hub ↔ Spoke-2 └─ Hub: "Allow gateway transit" = YES └─ Spoke-2: "Use remote gateway" = YES β–‘ Peer Hub ↔ Spoke-3 (repeat pattern) β–‘ Verify: Peering status = Connected

NSG Rules & Testing

░ Hub: Allow traffic from all spokes and on-prem ░ Spokes: Allow traffic from hub firewall only ░ Spokes: Allow internal subnet traffic (Web→App→DB) ░ Spokes: Block direct spoke-to-spoke (force through hub) ░ Test spoke → hub connectivity (peering works) ░ Test spoke → internet (routes through firewall) ░ Test spoke → on-prem (uses hub gateway) ░ Test spoke → other-spoke (routes through firewall) ░ Test firewall rules (inspect and allow/block)

How This Connects to Other Topics

Related to Module 01 (Identity & Governance)

  • RBAC: Only network admins can create peerings, modify hub routes
  • Policy: Enforce hub-and-spoke topology for all VNets

Related to Module 02 (Storage)

  • Storage Access: Spokes access storage through hub firewall

Related to Module 03 (Compute)

  • VM Communication: VMs in different spokes communicate via hub

Related to Module 05 (Monitor)

  • Monitor Hub: Track traffic through firewall and gateways
  • Network Watcher: Diagnose spoke-to-spoke connectivity issues

See It In Action

Associated labs:

Suggested learning sequence:

  1. βœ… Read VNets & Subnets
  2. βœ… Read NSGs
  3. βœ… Read Routing Fundamentals
  4. βœ… Read VNet Peering
  5. βœ… Read VPN & ExpressRoute
  6. βœ… Read this doc (Hub-Spoke Topology)
  7. βœ… Work through Labs 12-15 (implement hub-spoke)

Key Takeaways

πŸ’‘ Summary
  • Hub-Spoke = scalable network architecture (one hub, many spokes)
  • Hub contains shared services (VPN, firewall, DNS, shared resources)
  • Spokes don't peer directly (all traffic through hub for inspection)
  • Gateway transit = spokes use hub's VPN/ExpressRoute
  • Routing is key = UDRs direct spoke-to-spoke through firewall
  • Non-transitive peering = A↔B and B↔C doesn't mean A↔C
  • Plan CIDR upfront = No overlapping address spaces
  • NSGs enforce policy = Control which traffic is allowed

Next Steps

  1. Learn: Read this doc (you're here)
  2. Design: Draw your hub-spoke topology (CIDR, subnets, peerings)
  3. Implement: Work through Labs 12-15 (hands-on setup)
  4. Monitor: Track traffic flows through hub firewall
  5. Scale: Add spokes as new business units need Azure environments