Scenario: Credit Union Hybrid AVD in Canada Central (Toronto HQ)

Youโ€™re rolling out Azure Virtual Desktop (AVD) in Canada Central for 300 staff. Identity and core services still live on-prem in Toronto HQ (AD DS, DNS, file shares, legacy line-of-business apps). You need a Site-to-Site VPN so that:

  • AVD session hosts can join the domain
  • Users get low-friction access to on-prem resources (file shares, app servers)
  • You avoid exposing internal services to the public Internet

Target Design (at a glance)

Azure (Canada Central)

  • VNet: AVD-Prod-vNET
  • Address space: 10.50.0.0/16
  • Workload subnet: WorkloadSubnet = 10.50.10.0/24
  • GatewaySubnet: 10.50.255.0/27
  • VPN Gateway: AVD-VNGW-CC
  • Public IP: AVD-VNGW-CC-PIP
  • VPN: Route-based, IKEv2, Gen2, SKU VpnGw2

On-prem (Toronto HQ)

  • VPN device public IP: (your ISP-assigned public IP)
  • Private address space to route: 10.20.0.0/16 (HQ LAN), 10.21.0.0/16 (Server VLAN)

Lab 1: Build the Site-to-Site VPN using Azure Portal

Prereqs

  • Resource group: RG-AVD-Network-Prod
  • VNet already created: AVD-Prod-vNET
  • You have:
    • On-prem firewall/router that supports IPSec/IKEv2
    • A chosen PSK (shared key)

Step A: Create the Azure VPN Gateway

  1. Azure Portal โ†’ Search Virtual network gateways
  2. Click Create
  3. Configure:
    • Name: AVD-VNGW-CC
    • Region: Canada Central
    • Gateway type: VPN
    • VPN type: Route-based
    • SKU: VpnGw2
    • Generation: Gen2
    • Virtual network: AVD-Prod-vNET
    • Gateway subnet address range: 10.50.255.0/27
      (Azure will create the GatewaySubnet if it doesnโ€™t exist)
    • Public IP: Create new
      • Public IP name: AVD-VNGW-CC-PIP
    • Active-active: Disabled
    • BGP: Disabled
  4. Review + create โ†’ Create

Reality check: provisioning a VPN Gateway often takes a while. Donโ€™t panic if itโ€™s 20โ€“45 minutes in some tenants.


Step B: Create the Local Network Gateway (Toronto HQ representation)

  1. Azure Portal โ†’ Search Local network gateways
  2. Click Create
  3. Configure:
    • Name: LNG-TorontoHQ
    • Endpoint: IP address
    • IP address: ()
    • Address space:
      • 10.20.0.0/16
      • 10.21.0.0/16
    • BGP: Disabled
    • Region: Canada Central
    • Resource group: RG-AVD-Network-Prod
  4. Click Create

Step C: Create the S2S Connection

  1. Go to Virtual network gateways โ†’ AVD-VNGW-CC
  2. Left menu โ†’ Connections
  3. Click + Add
  4. Configure:
    • Name: Conn-AVD-CC-to-TorontoHQ
    • Connection type: Site-to-site (IPSec)
    • Virtual network gateway: AVD-VNGW-CC
    • Local network gateway: LNG-TorontoHQ
    • Shared key (PSK): ()
    • Enable BGP: Unticked
    • IKE Protocol: IKEv2
  5. Click Create
  6. Verify connection status shows Connected

What you configure on the Toronto firewall/router

Have these ready for the network team (or for your own change window):

  • Remote peer IP: Azure gateway public IP (from AVD-VNGW-CC-PIP)
  • Remote networks: 10.50.0.0/16 (or the exact Azure subnets you want reachable)
  • Local networks: 10.20.0.0/16, 10.21.0.0/16
  • PSK: exactly the same as the Azure Connection setting
  • IKEv2 + IPSec settings: must match proposals (encryption, integrity, DH group, lifetimes)
  • Confirm NAT rules are not unintentionally translating internal subnets in a way that breaks routing

Lab 2: Build the same S2S VPN using PowerShell (Az module)

Replace the placeholder values before running.

# Connect
Connect-AzAccount
# Set-AzContext -Subscription ""  # optional

$Location = "Canada Central"
$RgName   = "RG-AVD-Network-Prod"
$VnetName = "AVD-Prod-vNET"

# Azure VNet plan
$VnetAddressSpace     = "10.50.0.0/16"
$WorkloadSubnetName   = "WorkloadSubnet"
$WorkloadSubnetPrefix = "10.50.10.0/24"
$GatewaySubnetName    = "GatewaySubnet"
$GatewaySubnetPrefix  = "10.50.255.0/27"

# Gateway objects
$VpnGwName = "AVD-VNGW-CC"
$PipName   = "AVD-VNGW-CC-PIP"
$LngName   = "LNG-TorontoHQ"
$ConnName  = "Conn-AVD-CC-to-TorontoHQ"

# On-prem settings (replace)
$OnPremPublicIp        = "198.51.100.20"                 # Toronto firewall/router public IP
$OnPremAddressPrefixes = @("10.20.0.0/16","10.21.0.0/16") # On-prem routed networks
$SharedKey             = "REPLACE_WITH_STRONG_PSK"

# 1) Resource group
if (-not (Get-AzResourceGroup -Name $RgName -ErrorAction SilentlyContinue)) {
    New-AzResourceGroup -Name $RgName -Location $Location | Out-Null
}

# 2) VNet (create if missing) + ensure GatewaySubnet exists
$vnet = Get-AzVirtualNetwork -Name $VnetName -ResourceGroupName $RgName -ErrorAction SilentlyContinue

if (-not $vnet) {
    $subWork = New-AzVirtualNetworkSubnetConfig -Name $WorkloadSubnetName -AddressPrefix $WorkloadSubnetPrefix
    $subGw   = New-AzVirtualNetworkSubnetConfig -Name $GatewaySubnetName  -AddressPrefix $GatewaySubnetPrefix

    $vnet = New-AzVirtualNetwork `
        -Name $VnetName `
        -ResourceGroupName $RgName `
        -Location $Location `
        -AddressPrefix $VnetAddressSpace `
        -Subnet @($subWork, $subGw)
} else {
    $gwSubnet = Get-AzVirtualNetworkSubnetConfig -Name $GatewaySubnetName -VirtualNetwork $vnet -ErrorAction SilentlyContinue
    if (-not $gwSubnet) {
        Add-AzVirtualNetworkSubnetConfig -Name $GatewaySubnetName -AddressPrefix $GatewaySubnetPrefix -VirtualNetwork $vnet | Out-Null
        $vnet = Set-AzVirtualNetwork -VirtualNetwork $vnet
    }
}

$gwSubnet = Get-AzVirtualNetworkSubnetConfig -Name $GatewaySubnetName -VirtualNetwork $vnet

# 3) Public IP
$pip = New-AzPublicIpAddress `
    -Name $PipName `
    -ResourceGroupName $RgName `
    -Location $Location `
    -Sku Standard `
    -AllocationMethod Static

# 4) Gateway IP config
$gwIpConfig = New-AzVirtualNetworkGatewayIpConfig `
    -Name "gwipconfig1" `
    -SubnetId $gwSubnet.Id `
    -PublicIpAddressId $pip.Id

# 5) Create VPN Gateway
$vng = New-AzVirtualNetworkGateway `
    -Name $VpnGwName `
    -ResourceGroupName $RgName `
    -Location $Location `
    -IpConfigurations $gwIpConfig `
    -GatewayType Vpn `
    -VpnType RouteBased `
    -GatewaySku VpnGw2 `
    -VpnGatewayGeneration "Generation2" `
    -EnableBgp $false

# 6) Local Network Gateway
$lng = New-AzLocalNetworkGateway `
    -Name $LngName `
    -ResourceGroupName $RgName `
    -Location $Location `
    -GatewayIpAddress $OnPremPublicIp `
    -AddressPrefix $OnPremAddressPrefixes

# 7) S2S Connection
$conn = New-AzVirtualNetworkGatewayConnection `
    -Name $ConnName `
    -ResourceGroupName $RgName `
    -Location $Location `
    -VirtualNetworkGateway1 $vng `
    -LocalNetworkGateway2 $lng `
    -ConnectionType IPsec `
    -SharedKey $SharedKey `
    -EnableBgp $false

# 8) Verify
Get-AzVirtualNetworkGatewayConnection -Name $ConnName -ResourceGroupName $RgName |
  Select-Object Name, ConnectionStatus, IngressBytesTransferred, EgressBytesTransferred

Verification Checklist (the โ€œdonโ€™t leave until this is greenโ€ list)

Azure-side checks

  • VPN Gateway deployment: Succeeded
  • Connection: Connected
  • GatewaySubnet exists and is correct: 10.50.255.0/27

Routing checks

  • No overlapping CIDRs (Azure and on-prem)
  • On-prem device routes include Azure address space (10.50.0.0/16)
  • Local Network Gateway includes every on-prem subnet you expect to reach

Functional tests (recommended)

From an Azure VM in WorkloadSubnet:

  • Ping is often blocked. Prefer TCP tests:
    • Test-NetConnection -Port 53
    • Test-NetConnection -Port 389 (LDAP)
    • Test-NetConnection -Port 445 (SMB)
    • nslookup yourdomain.local

How this ties back to AVD (practical purpose)

Once S2S is up, you can confidently deploy:

  • AVD session hosts that domain-join to on-prem AD DS
  • FSLogix profile storage on a file share that AVD hosts can reach
  • Legacy app dependencies that still run on-prem

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *