Skip to main content

Challenge 22: Virtual WAN hub-spoke

Estimated time and cost

90–120 minutes | ~$0.36/h (Virtual WAN Standard + VPN Gateway) | Exam weight: 20–25%

Scenario

Contoso is migrating from a manually configured hub-spoke topology (VNet peering with user-defined routes) to Azure Virtual WAN for simplified branch and spoke connectivity management. They operate in two Azure regions -- East US and West Europe -- and need automated spoke-to-spoke connectivity, integrated VPN gateways for branch offices, and centralized routing without maintaining UDR tables manually.

Their current architecture requires dozens of peering relationships and route tables. The network team wants to consolidate this into a Virtual WAN Standard deployment that supports transit routing between spokes, site-to-site VPN for on-premises branches, and future ExpressRoute integration.

Exam skills measured

SkillDescription
Select a Virtual WAN SKUChoose between Basic and Standard based on connectivity requirements
Design a Virtual WAN architectureSelect types and services including hub placement and gateway types
Create a virtual hub in Virtual WANDeploy hubs with correct address prefixes and SKU settings
Choose an appropriate scale unitSize gateway scale units for throughput and connection requirements
Deploy a gateway into a virtual hubProvision VPN gateways within the virtual hub infrastructure

Architecture overview

On-premises Branch[VPN Site]Virtual WAN (Standard)Hub East US10.1.0.0/24VPN GatewayHub West Europe10.2.0.0/24VPN GatewaySpoke1Spoke2Spoke3Spoke4Spoke5Connected VNetsConnected VNets

Key concepts

Virtual WAN SKU comparison

FeatureBasicStandard
Site-to-site VPNYesYes
Point-to-site VPNNoYes
ExpressRouteNoYes
VNet-to-VNet transit through hubNoYes
Hub-to-hub connectivityNoYes
Azure Firewall in hubNoYes
NVA in hubNoYes

Scale units

Each VPN gateway scale unit provides approximately 500 Mbps of aggregate throughput. Common configurations:

Scale unitsAggregate throughputMax S2S connections
1500 Mbps500
21 Gbps500
2010 Gbps1000
4020 Gbps2000

Task 1: Create the Virtual WAN resource

Provision a Virtual WAN resource with the Standard SKU to support transit routing, multiple gateway types, and hub-to-hub communication.

Azure CLI

# Define variables
RG="rg-vwan-challenge22"
LOCATION="eastus"
VWAN_NAME="vwan-contoso"

# Create resource group
az group create \
--name $RG \
--location $LOCATION

# Create Virtual WAN with Standard SKU
az network vwan create \
--name $VWAN_NAME \
--resource-group $RG \
--location $LOCATION \
--type Standard \
--branch-to-branch-traffic true

Azure PowerShell

# Define variables
$RG = "rg-vwan-challenge22"
$Location = "eastus"
$VwanName = "vwan-contoso"

# Create resource group
New-AzResourceGroup -Name $RG -Location $Location

# Create Virtual WAN with Standard SKU
New-AzVirtualWan `
-ResourceGroupName $RG `
-Name $VwanName `
-Location $Location `
-VirtualWANType Standard `
-AllowBranchToBranchTraffic
Why Standard?

The Basic SKU only supports site-to-site VPN. It does not support spoke-to-spoke transit, ExpressRoute, point-to-site, Azure Firewall, or hub-to-hub connectivity. For most enterprise deployments, Standard is required.


Task 2: Create a virtual hub in the primary region

Deploy a virtual hub in East US with a dedicated address prefix. The hub address space must not overlap with any connected spoke VNets.

Azure CLI

# Create virtual hub in East US
az network vhub create \
--name "hub-eastus" \
--resource-group $RG \
--vwan $VWAN_NAME \
--address-prefix "10.1.0.0/24" \
--location "eastus" \
--sku Standard

Azure PowerShell

# Get the Virtual WAN object
$vwan = Get-AzVirtualWan -ResourceGroupName $RG -Name $VwanName

# Create virtual hub in East US
New-AzVirtualHub `
-ResourceGroupName $RG `
-Name "hub-eastus" `
-VirtualWan $vwan `
-AddressPrefix "10.1.0.0/24" `
-Location "eastus" `
-HubRoutingPreference "VpnGateway"
Hub provisioning time

Virtual hub creation takes 20-30 minutes. The hub must reach Succeeded provisioning state before you can connect spokes or deploy gateways. Monitor the status with:

az network vhub show --name "hub-eastus" --resource-group $RG --query "provisioningState"

Task 3: Create spoke VNets and connect them to the hub

Create spoke VNets and establish connections to the virtual hub. Virtual WAN automatically handles routing between connected spokes.

Azure CLI

# Create spoke VNets
az network vnet create \
--name "vnet-spoke1" \
--resource-group $RG \
--location "eastus" \
--address-prefixes "10.10.0.0/16" \
--subnet-name "workload" \
--subnet-prefixes "10.10.1.0/24"

az network vnet create \
--name "vnet-spoke2" \
--resource-group $RG \
--location "eastus" \
--address-prefixes "10.20.0.0/16" \
--subnet-name "workload" \
--subnet-prefixes "10.20.1.0/24"

# Connect spoke1 to the virtual hub
az network vhub connection create \
--name "conn-spoke1" \
--resource-group $RG \
--vhub-name "hub-eastus" \
--remote-vnet "vnet-spoke1" \
--internet-security true

# Connect spoke2 to the virtual hub
az network vhub connection create \
--name "conn-spoke2" \
--resource-group $RG \
--vhub-name "hub-eastus" \
--remote-vnet "vnet-spoke2" \
--internet-security true

Azure PowerShell

# Create spoke VNets
$spoke1 = New-AzVirtualNetwork `
-ResourceGroupName $RG `
-Name "vnet-spoke1" `
-Location "eastus" `
-AddressPrefix "10.10.0.0/16"

Add-AzVirtualNetworkSubnetConfig `
-Name "workload" `
-VirtualNetwork $spoke1 `
-AddressPrefix "10.10.1.0/24"
$spoke1 | Set-AzVirtualNetwork

$spoke2 = New-AzVirtualNetwork `
-ResourceGroupName $RG `
-Name "vnet-spoke2" `
-Location "eastus" `
-AddressPrefix "10.20.0.0/16"

Add-AzVirtualNetworkSubnetConfig `
-Name "workload" `
-VirtualNetwork $spoke2 `
-AddressPrefix "10.20.1.0/24"
$spoke2 | Set-AzVirtualNetwork

# Get hub object
$hub = Get-AzVirtualHub -ResourceGroupName $RG -Name "hub-eastus"

# Connect spoke1
$spoke1Ref = Get-AzVirtualNetwork -ResourceGroupName $RG -Name "vnet-spoke1"
New-AzVirtualHubVnetConnection `
-ResourceGroupName $RG `
-VirtualHubName "hub-eastus" `
-Name "conn-spoke1" `
-RemoteVirtualNetwork $spoke1Ref `
-EnableInternetSecurity $true

# Connect spoke2
$spoke2Ref = Get-AzVirtualNetwork -ResourceGroupName $RG -Name "vnet-spoke2"
New-AzVirtualHubVnetConnection `
-ResourceGroupName $RG `
-VirtualHubName "hub-eastus" `
-Name "conn-spoke2" `
-RemoteVirtualNetwork $spoke2Ref `
-EnableInternetSecurity $true

Task 4: Deploy a VPN gateway in the virtual hub

Deploy a site-to-site VPN gateway within the hub. Select scale units based on required throughput -- Contoso needs 1 Gbps aggregate bandwidth.

Azure CLI

# Deploy VPN gateway in the hub (scale unit 2 = ~1 Gbps)
az network vpn-gateway create \
--name "vpngw-hub-eastus" \
--resource-group $RG \
--vhub "hub-eastus" \
--location "eastus" \
--scale-unit 2 \
--no-wait

Azure PowerShell

# Deploy VPN gateway in the hub (scale unit 2 = ~1 Gbps)
New-AzVpnGateway `
-ResourceGroupName $RG `
-Name "vpngw-hub-eastus" `
-VirtualHub $hub `
-VpnGatewayScaleUnit 2
Gateway provisioning

VPN gateway creation inside a virtual hub takes 25-45 minutes. Do not proceed to creating connections until the gateway reaches Succeeded state:

az network vpn-gateway show \
--name "vpngw-hub-eastus" \
--resource-group $RG \
--query "provisioningState"

Task 5: Create a VPN site and connection

Define the on-premises branch as a VPN site and create the S2S connection through the Virtual WAN VPN gateway.

Azure CLI

# Create a VPN site representing the on-premises branch
az network vpn-site create \
--name "site-branch-nyc" \
--resource-group $RG \
--location "eastus" \
--ip-address "203.0.113.10" \
--address-prefixes "192.168.0.0/16" \
--virtual-wan $VWAN_NAME \
--device-vendor "Cisco" \
--device-model "ISR4321" \
--link-speed 100

# Create the VPN gateway connection to the site
az network vpn-gateway connection create \
--name "conn-branch-nyc" \
--resource-group $RG \
--gateway-name "vpngw-hub-eastus" \
--remote-vpn-site "site-branch-nyc"

Azure PowerShell

# Create a VPN site representing the on-premises branch
$vpnSite = New-AzVpnSite `
-ResourceGroupName $RG `
-Name "site-branch-nyc" `
-Location "eastus" `
-IpAddress "203.0.113.10" `
-AddressSpace @("192.168.0.0/16") `
-VirtualWanResourceGroupName $RG `
-VirtualWanName $VwanName `
-DeviceModel "ISR4321" `
-DeviceVendor "Cisco" `
-LinkSpeedInMbps 100

# Create VPN gateway connection
$vpnSiteObj = Get-AzVpnSite -ResourceGroupName $RG -Name "site-branch-nyc"
$vpnGw = Get-AzVpnGateway -ResourceGroupName $RG -Name "vpngw-hub-eastus"

New-AzVpnConnection `
-ResourceGroupName $RG `
-ParentResourceName "vpngw-hub-eastus" `
-Name "conn-branch-nyc" `
-VpnSite $vpnSiteObj

Task 6: Verify spoke-to-spoke connectivity

With Standard SKU, spoke-to-spoke transit routing is automatic through the hub. Verify by checking the effective routes on spoke connections.

Azure CLI

# Check effective routes for the virtual hub
az network vhub get-effective-routes \
--name "hub-eastus" \
--resource-group $RG

# Verify hub connection status
az network vhub connection show \
--name "conn-spoke1" \
--resource-group $RG \
--vhub-name "hub-eastus" \
--query "{name:name, status:provisioningState, routingConfig:routingConfiguration}"

# List all connections on the hub
az network vhub connection list \
--resource-group $RG \
--vhub-name "hub-eastus" \
--output table

Azure PowerShell

# Get hub connection details
Get-AzVirtualHubVnetConnection `
-ResourceGroupName $RG `
-VirtualHubName "hub-eastus" |
Select-Object Name, ProvisioningState, RoutingConfiguration

# Verify hub effective routes
Get-AzVirtualHubEffectiveRoute `
-ResourceGroupName $RG `
-VirtualHubName "hub-eastus"

Break & fix

Scenario 1: Basic SKU with VPN gateway fails

Symptom: Attempting to deploy a VPN gateway fails with an error about unsupported features.

Root cause: The Virtual WAN was created with --type Basic but gateways other than basic S2S VPN require Standard SKU. Additionally, Basic does not support spoke-to-spoke transit.

Fix:

# Upgrade from Basic to Standard
az network vwan update \
--name $VWAN_NAME \
--resource-group $RG \
--type Standard
note

Upgrading from Basic to Standard is a non-disruptive operation. However, downgrading from Standard to Basic is not supported.


Scenario 2: Spoke connectivity not working after hub connection

Symptom: VMs in spoke VNets cannot reach each other even though connections show Succeeded status.

Root cause: The virtual hub has not fully provisioned its routing infrastructure. The hub routing state must be Provisioned (not just the connection).

Diagnosis:

# Check hub routing state
az network vhub show \
--name "hub-eastus" \
--resource-group $RG \
--query "{routingState:routingState, provisioningState:provisioningState}"

Fix: Wait for routingState to show Provisioned. If stuck, remove and recreate the connection:

az network vhub connection delete \
--name "conn-spoke1" \
--resource-group $RG \
--vhub-name "hub-eastus" \
--yes

# Wait 2 minutes, then recreate
az network vhub connection create \
--name "conn-spoke1" \
--resource-group $RG \
--vhub-name "hub-eastus" \
--remote-vnet "vnet-spoke1"

Scenario 3: Insufficient throughput from VPN gateway

Symptom: Branch office reports slow connectivity. Monitoring shows the VPN gateway is saturated at 500 Mbps.

Root cause: The gateway was deployed with scale unit 1, providing only 500 Mbps aggregate throughput.

Fix:

# Update the VPN gateway scale unit
az network vpn-gateway update \
--name "vpngw-hub-eastus" \
--resource-group $RG \
--scale-unit 4

Cleanup

# Delete the entire resource group and all resources
az group delete --name $RG --yes --no-wait
# PowerShell cleanup
Remove-AzResourceGroup -Name "rg-vwan-challenge22" -Force -AsJob
![Challenge 22 - Network Topology](/img/az-700/challenge-22-topology.svg)