Skip to main content

Challenge 15: S2S VPN high availability and multi-site

Estimated time and cost

75-120 minutes | ~$0.55/h (VpnGw2AZ SKU) | Exam weight: 20-25%

Deployment time

Active-active VPN Gateway provisioning takes 30-45 minutes. Use --no-wait and continue with conceptual learning while the gateway deploys.

Scenario

Contoso's site-to-site VPN established in Challenge 14 uses a single VPN gateway instance, creating a single point of failure. During a recent Azure maintenance event, the VPN tunnel went down for 15 minutes causing a business disruption. The networking team must implement high availability for the VPN gateway using active-active configuration with zone-redundant SKUs, connect to multiple on-premises sites, and configure BGP for dynamic route exchange. Additionally, the team needs to understand Azure Extended Network for an upcoming Layer 2 migration project.

Architecture:

Challenge 15 - Network Topology

Learning objectives

After completing this challenge you will be able to:

  • Design and implement a high-availability site-to-site VPN connection
  • Deploy an active-active VPN gateway with zone-redundant SKUs
  • Configure BGP on VPN gateways for dynamic routing
  • Connect multiple on-premises sites to a single VPN gateway (multi-site)
  • Explain the purpose and use case for Azure Extended Network

Prerequisites

  • Completion of Challenge 14 (or understanding of basic S2S VPN concepts)
  • An Azure subscription with Contributor access
  • Azure CLI installed and authenticated (az login)
  • PowerShell with Az module installed

Key concepts for AZ-700

ConceptDetail
Active-active gatewayTwo gateway instances, each with its own public IP; both tunnels active simultaneously
Zone-redundant gatewaySKUs ending in "AZ" (e.g., VpnGw2AZ) deploy instances across availability zones
BGP (Border Gateway Protocol)Dynamic routing protocol; advertises routes automatically instead of static local-address-prefixes
ASN (Autonomous System Number)Unique identifier for a BGP speaker; Azure default is 65515
Multi-site VPNMultiple local network gateways connected to a single VPN gateway (one connection per site)
Azure Extended NetworkLayer 2 overlay that stretches an on-prem subnet into Azure for live migration without re-IP

Active-active vs active-standby

FeatureActive-standby (default)Active-active
Gateway instances2 (one active, one standby)2 (both active)
Public IPs12 (one per instance)
Failover time60-90 secondsNear-instant (other tunnel already active)
Tunnels per site12 (one to each instance)
On-prem configurationSingle tunnel to one IPTwo tunnels to two IPs
ThroughputSingle instance bandwidthAggregated bandwidth from both instances

Zone-redundant SKU naming

Standard SKUZone-redundant equivalent
VpnGw1VpnGw1AZ
VpnGw2VpnGw2AZ
VpnGw3VpnGw3AZ
VpnGw4VpnGw4AZ
VpnGw5VpnGw5AZ

Zone-redundant SKUs require Standard SKU public IPs (not Basic) with zone-redundant allocation.


Task 1: Deploy an active-active zone-redundant VPN gateway

Step 1: Create the resource group and VNet

az group create \
--name rg-vpn-ha-lab \
--location eastus

az network vnet create \
--resource-group rg-vpn-ha-lab \
--name vnet-hub \
--location eastus \
--address-prefixes 10.1.0.0/16 \
--subnet-name snet-workloads \
--subnet-prefixes 10.1.1.0/24

az network vnet subnet create \
--resource-group rg-vpn-ha-lab \
--vnet-name vnet-hub \
--name GatewaySubnet \
--address-prefixes 10.1.255.0/27

Step 2: Create two zone-redundant public IPs (required for active-active)

az network public-ip create \
--resource-group rg-vpn-ha-lab \
--name pip-vgw-hub-1 \
--location eastus \
--allocation-method Static \
--sku Standard \
--zone 1 2 3

az network public-ip create \
--resource-group rg-vpn-ha-lab \
--name pip-vgw-hub-2 \
--location eastus \
--allocation-method Static \
--sku Standard \
--zone 1 2 3
Zone-redundant public IPs

When using zone-redundant gateway SKUs (ending in AZ), the public IPs must be Standard SKU. Specifying --zone 1 2 3 makes the IP zone-redundant, meaning it survives the failure of any single availability zone.

Step 3: Create the active-active VPN gateway

az network vnet-gateway create \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--vnet vnet-hub \
--gateway-type Vpn \
--vpn-type RouteBased \
--sku VpnGw2AZ \
--public-ip-addresses pip-vgw-hub-1 pip-vgw-hub-2 \
--active-active \
--no-wait

Azure PowerShell

# Create public IPs
$pip1 = New-AzPublicIpAddress `
-ResourceGroupName "rg-vpn-ha-lab" `
-Name "pip-vgw-hub-1" `
-Location "eastus" `
-AllocationMethod Static `
-Sku Standard `
-Zone 1, 2, 3

$pip2 = New-AzPublicIpAddress `
-ResourceGroupName "rg-vpn-ha-lab" `
-Name "pip-vgw-hub-2" `
-Location "eastus" `
-AllocationMethod Static `
-Sku Standard `
-Zone 1, 2, 3

# Get subnet reference
$vnet = Get-AzVirtualNetwork -ResourceGroupName "rg-vpn-ha-lab" -Name "vnet-hub"
$gwSubnet = Get-AzVirtualNetworkSubnetConfig -Name "GatewaySubnet" -VirtualNetwork $vnet

# Create two IP configurations (one per public IP)
$ipConfig1 = New-AzVirtualNetworkGatewayIpConfig `
-Name "gwIpConfig1" `
-SubnetId $gwSubnet.Id `
-PublicIpAddressId $pip1.Id

$ipConfig2 = New-AzVirtualNetworkGatewayIpConfig `
-Name "gwIpConfig2" `
-SubnetId $gwSubnet.Id `
-PublicIpAddressId $pip2.Id

# Create active-active VPN gateway
New-AzVirtualNetworkGateway `
-ResourceGroupName "rg-vpn-ha-lab" `
-Name "vgw-hub-ha" `
-Location "eastus" `
-IpConfigurations $ipConfig1, $ipConfig2 `
-GatewayType Vpn `
-VpnType RouteBased `
-GatewaySku VpnGw2AZ `
-EnableActiveActiveFeature `
-AsJob

Task 2: Connect multiple on-premises sites (multi-site VPN)

Step 1: Create local network gateways for each site

# Site A: Dallas datacenter
az network local-gateway create \
--resource-group rg-vpn-ha-lab \
--name lgw-dallas \
--gateway-ip-address 203.0.113.10 \
--local-address-prefixes 10.10.0.0/16 \
--location eastus

# Site B: Chicago datacenter
az network local-gateway create \
--resource-group rg-vpn-ha-lab \
--name lgw-chicago \
--gateway-ip-address 198.51.100.25 \
--local-address-prefixes 10.20.0.0/16 \
--location eastus

Step 2: Create VPN connections to each site

# Connection to Dallas
az network vpn-connection create \
--resource-group rg-vpn-ha-lab \
--name conn-to-dallas \
--vnet-gateway1 vgw-hub-ha \
--local-gateway2 lgw-dallas \
--shared-key "DallasKey!2024Secure"

# Connection to Chicago
az network vpn-connection create \
--resource-group rg-vpn-ha-lab \
--name conn-to-chicago \
--vnet-gateway1 vgw-hub-ha \
--local-gateway2 lgw-chicago \
--shared-key "ChicagoKey!2024Secure"

Azure PowerShell

# Create local gateways
$lgwDallas = New-AzLocalNetworkGateway `
-ResourceGroupName "rg-vpn-ha-lab" `
-Name "lgw-dallas" `
-Location "eastus" `
-GatewayIpAddress "203.0.113.10" `
-AddressPrefix "10.10.0.0/16"

$lgwChicago = New-AzLocalNetworkGateway `
-ResourceGroupName "rg-vpn-ha-lab" `
-Name "lgw-chicago" `
-Location "eastus" `
-GatewayIpAddress "198.51.100.25" `
-AddressPrefix "10.20.0.0/16"

# Create connections
$vgw = Get-AzVirtualNetworkGateway -ResourceGroupName "rg-vpn-ha-lab" -Name "vgw-hub-ha"

New-AzVirtualNetworkGatewayConnection `
-ResourceGroupName "rg-vpn-ha-lab" `
-Name "conn-to-dallas" `
-Location "eastus" `
-VirtualNetworkGateway1 $vgw `
-LocalNetworkGateway2 $lgwDallas `
-ConnectionType IPsec `
-SharedKey "DallasKey!2024Secure"

New-AzVirtualNetworkGatewayConnection `
-ResourceGroupName "rg-vpn-ha-lab" `
-Name "conn-to-chicago" `
-Location "eastus" `
-VirtualNetworkGateway1 $vgw `
-LocalNetworkGateway2 $lgwChicago `
-ConnectionType IPsec `
-SharedKey "ChicagoKey!2024Secure"
Multi-site considerations
  • Each on-premises site requires its own local network gateway and VPN connection resource
  • Route-based VPN gateways support up to 30 S2S tunnels (VpnGw1) or 100 (VpnGw4/5)
  • Address spaces across all local network gateways must not overlap
  • Each connection can have a different shared key

Task 3: Configure BGP on the VPN gateway

BGP enables dynamic route exchange, eliminating the need to manually maintain --local-address-prefixes on local network gateways when on-premises networks change.

Step 1: Enable BGP on the VPN gateway

az network vnet-gateway update \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--enable-bgp true \
--asn 65010

Step 2: Create a BGP-enabled local network gateway

When using BGP, the local network gateway includes the on-premises BGP peer IP and ASN:

az network local-gateway create \
--resource-group rg-vpn-ha-lab \
--name lgw-dallas-bgp \
--gateway-ip-address 203.0.113.10 \
--local-address-prefixes 10.10.0.0/16 \
--bgp-peering-address 10.10.255.254 \
--asn 65020 \
--location eastus

Step 3: Create a BGP-enabled connection

az network vpn-connection create \
--resource-group rg-vpn-ha-lab \
--name conn-to-dallas-bgp \
--vnet-gateway1 vgw-hub-ha \
--local-gateway2 lgw-dallas-bgp \
--shared-key "DallasBGP!2024Key" \
--enable-bgp true

Azure PowerShell

# Update gateway with BGP
$vgw = Get-AzVirtualNetworkGateway -ResourceGroupName "rg-vpn-ha-lab" -Name "vgw-hub-ha"
$vgw.EnableBgp = $true
$vgw.BgpSettings.Asn = 65010
Set-AzVirtualNetworkGateway -VirtualNetworkGateway $vgw

# Create BGP-enabled local gateway
$lgwDallasBgp = New-AzLocalNetworkGateway `
-ResourceGroupName "rg-vpn-ha-lab" `
-Name "lgw-dallas-bgp" `
-Location "eastus" `
-GatewayIpAddress "203.0.113.10" `
-AddressPrefix "10.10.0.0/16" `
-BgpPeeringAddress "10.10.255.254" `
-Asn 65020

# Create connection with BGP
New-AzVirtualNetworkGatewayConnection `
-ResourceGroupName "rg-vpn-ha-lab" `
-Name "conn-to-dallas-bgp" `
-Location "eastus" `
-VirtualNetworkGateway1 $vgw `
-LocalNetworkGateway2 $lgwDallasBgp `
-ConnectionType IPsec `
-SharedKey "DallasBGP!2024Key" `
-EnableBgp $true

Step 4: Verify BGP configuration

# Show gateway BGP settings
az network vnet-gateway show \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--query "{bgpEnabled:enableBgp, asn:bgpSettings.asn, peerAddress:bgpSettings.bgpPeeringAddress}" \
--output table

# List learned BGP routes
az network vnet-gateway list-learned-routes \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--output table

# List advertised routes to a specific peer
az network vnet-gateway list-advertised-routes \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--peer 10.10.255.254 \
--output table
BGP ASN rules
  • Azure reserved ASN: 65515 (default for Azure VPN gateways if not specified)
  • Do not use 65515 for on-premises devices
  • Private ASN range: 64512-65534 and 4200000000-4294967294
  • Each BGP peer (Azure gateway and on-prem device) must have a unique ASN
  • The --bgp-peering-address on the local network gateway is the on-prem device's internal BGP peer IP (not its public IP)

Task 4: Verify active-active gateway instances

Azure CLI

# Show both public IPs assigned to the active-active gateway
az network vnet-gateway show \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--query "ipConfigurations[].{name:name, publicIP:publicIpAddress.id}" \
--output table

# Show both tunnel IPs
az network public-ip show \
--resource-group rg-vpn-ha-lab \
--name pip-vgw-hub-1 \
--query "ipAddress" \
--output tsv

az network public-ip show \
--resource-group rg-vpn-ha-lab \
--name pip-vgw-hub-2 \
--query "ipAddress" \
--output tsv

Azure PowerShell

# Verify active-active configuration
$vgw = Get-AzVirtualNetworkGateway -ResourceGroupName "rg-vpn-ha-lab" -Name "vgw-hub-ha"
$vgw.ActiveActive
$vgw.IpConfigurations | Format-Table Name, PublicIpAddress

Task 5: Simulate failover

In an active-active configuration, if one gateway instance becomes unavailable, the on-premises device detects the dead peer (via IKE Dead Peer Detection) and fails over to the remaining active tunnel. No Azure-side action is required.

Verification steps

# Monitor connection status for both tunnels
az network vpn-connection show \
--resource-group rg-vpn-ha-lab \
--name conn-to-dallas \
--query "{status:connectionStatus, tunnelStatus:tunnelConnectionStatus}" \
--output json

Understanding failover behavior

ScenarioActive-standby behaviorActive-active behavior
Planned maintenance60-90 second downtimeNear-zero downtime (other tunnel remains)
Zone failureGateway unavailable if in affected zoneSurvives if using AZ SKU across zones
Single instance failure60-90 second failover to standbyImmediate use of other active tunnel
On-prem device failureTunnel down until device recoversTunnel down until device recovers (same)

Task 6: Azure Extended Network (conceptual)

Azure Extended Network is a Layer 2 overlay technology that stretches an on-premises subnet into an Azure VNet, allowing VMs to retain their on-premises IP addresses when migrated to Azure.

Use case

  • Live migration of VMs from on-premises to Azure without changing IP addresses
  • Avoid re-IP during phased migration projects
  • Maintain network dependencies (hardcoded IPs, legacy apps) during transition

Requirements and limitations

RequirementDetail
On-premisesWindows Server 2019+ with Hyper-V
AzureWindows Server 2019+ VMs in Azure
NetworkSite-to-site VPN or ExpressRoute between on-prem and Azure
Subnet/24 maximum for the stretched subnet
ScopeIntended for migration only, not long-term production use

How it works

  1. A pair of appliance VMs (one on-prem, one in Azure) create a VXLAN tunnel over the S2S VPN
  2. ARP and broadcast traffic is proxied between the two sides
  3. VMs on either side of the stretched subnet can communicate at Layer 2
  4. After migration is complete, the on-prem end is decommissioned
Exam note

Azure Extended Network is a niche topic on the exam. Key points to remember: it requires Windows Server 2019+, works over existing S2S VPN or ExpressRoute, is limited to /24 subnets, and is designed as a temporary migration aid (not a permanent architecture). If the exam asks about stretching Layer 2 to Azure, this is the answer.

Reference commands (conceptual only)

Azure Extended Network is configured through Windows Admin Center, not via Azure CLI or PowerShell directly:

  1. Install the Azure Extended Network extension in Windows Admin Center
  2. Connect to the on-premises host
  3. Select the subnet to extend
  4. Specify the Azure VNet and subnet to extend into
  5. Deploy the Azure appliance VM

For details, see Azure Extended Network documentation.


Break & fix

Scenario 1: BGP ASN conflict

Symptom: BGP peering fails to establish. Connection shows Connected but no routes are learned.

Root cause: Both the Azure VPN gateway and the on-premises device are configured with the same ASN (e.g., both using 65515).

Diagnostic command:

az network vnet-gateway show \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--query "bgpSettings.asn" \
--output tsv

az network local-gateway show \
--resource-group rg-vpn-ha-lab \
--name lgw-dallas-bgp \
--query "bgpSettings.asn" \
--output tsv

Fix: Change one side to a unique ASN:

az network vnet-gateway update \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--asn 65010

Scenario 2: Active-active with only one public IP

Symptom: Gateway creation fails or falls back to active-standby mode.

Root cause: Only one public IP was specified in --public-ip-addresses when creating the gateway. Active-active requires exactly two public IPs.

Fix: Recreate the gateway with two public IPs (cannot add a second IP after creation):

# Delete and recreate (gateway update cannot add active-active after creation)
az network vnet-gateway delete \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--no-wait

# Recreate with two public IPs
az network vnet-gateway create \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--vnet vnet-hub \
--gateway-type Vpn \
--vpn-type RouteBased \
--sku VpnGw2AZ \
--public-ip-addresses pip-vgw-hub-1 pip-vgw-hub-2 \
--active-active \
--no-wait

Scenario 3: Non-AZ SKU in zone-redundant configuration

Symptom: Gateway deploys but does not survive availability zone failure. Inspection shows instances in a single zone.

Root cause: A non-AZ SKU (e.g., VpnGw2 instead of VpnGw2AZ) was used. Non-AZ SKUs deploy both instances in the same zone or no specific zone.

Diagnostic command:

az network vnet-gateway show \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--query "sku.name" \
--output tsv
# Returns: VpnGw2 (should be VpnGw2AZ)

Fix: Recreate the gateway with an AZ SKU (SKU change requires delete and recreate):

az network vnet-gateway delete \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--no-wait

az network vnet-gateway create \
--resource-group rg-vpn-ha-lab \
--name vgw-hub-ha \
--vnet vnet-hub \
--gateway-type Vpn \
--vpn-type RouteBased \
--sku VpnGw2AZ \
--public-ip-addresses pip-vgw-hub-1 pip-vgw-hub-2 \
--active-active \
--no-wait

Knowledge check

1. How many public IP addresses are required for an active-active VPN gateway?

2. Which VPN Gateway SKU provides zone-redundant deployment across availability zones?

3. What is the default ASN assigned to Azure VPN gateways if no custom ASN is specified?

4. What is the primary use case for Azure Extended Network?

5. What happens during planned Azure maintenance on an active-active VPN gateway?


Cleanup

Remove all resources created in this challenge to stop billing:

az group delete --name rg-vpn-ha-lab --yes --no-wait
Remove-AzResourceGroup -Name "rg-vpn-ha-lab" -Force -AsJob

Additional references