Step-By-Step: Multi-Site Azure VPN Revisited

Hello Folks,

A while back I wrote about Multi-Site VPNs in Azure in the Resource Manager Model. Since then I've been reconsidering my design for a number of reasons:

  • a fully meshed VPN configuration grows in complexity with each added site\virtual network
  • the Basic and Standard Dynamic Routing gateways only support a maximum of 10 combined connections. High Performance VPN gateways supports 30.  in my last design each gateway had 6 connections already and i was only connecting 4 virtual networks together.

According to the pricing calculator, a Basic VPN Gateway costs with 1TB of Outbound Inter-VNET data transfers costs about CDN$76.14/month versus CDN$215.46/month for a Standard VPN Gateway. (pricing subject to change… )

image

So the fully meshed method works great and is a lot cheaper to operate.  But what if you need more sites?  for example, if you need to interconnect 10 Azure Vnets with one physical locations?  If you go the “full Meshed” model you could end up with the following:

image

This model would have 10 connections per gateway which is the maximum number of connections that Basic and Standard gateways can support.  There is a another way we can interconnect these VNets.  By changing to a Standard or HighPerformance, we can now leverage BGP (Border Gateway Protocol) to simplify our design and take advantage of transitive routing.  BGP is as you may know, is a standardized gateway protocol designed to exchange routing and reachability information among autonomous systems (AS).  Watch the following video for more information on BGP support in Azure

Step 1: Plan your IP Address Space

In this post, I'll recreate the same interconnected VNets as I did in the original post.  Minus the on-prem location. It will look like this.

image

 

This will allow connectivity everywhere.

Step 2 – Connect to your subscription, create the Resource Groups, Virtual Networks and Virtual Network Gateways

I used PowerShell to create my environment so let’s look at each part of the script in details.  Since this is for the Resource Manager Model if you have not done so before, you need to update your PowerShell from https://azure.microsoft.com/en-us/downloads and you should install the ARM modules by using the following commands.

 #To install the Resource Manager module directly from the Gallery,
#open Windows PowerShell as administrator and type the following:
Install-Module AzureRM
Install-AzureRM

#Once you have installed the modules, you need to import them in order to use them
Import-AzureRM

Once that is done. (and it may take a while), proceed to connect to your subscription.  We use Login-AzureRmAccount command to authenticate. The Resource Manager modules requires Login-AzureRmAccount. A Publish Settings file is not sufficient.

 #region 1 - Open your PowerShell console and connect to your account. Use the following sample to help you connect
Login-AzureRmAccount

#connect to your subscriptions for the account.
$subID=Get-AzureRmSubscription|Select-AzureRmSubscription

#endregion

At this point we are pretty much exactly where our old method took us.  I have streamlined the script (with the help of Sean Kearney, PowerShell MVP) by using a set of variables and a short script that will create :

  • The Resource Groups
  • the virtual networks with subnets
  • the VPN gateways

Here is the variable section.  You can see that I have 4 sites

  • East 1 = Array slot 0
  • East 2 = Array slot 1
  • West 1 = Array slot 2
  • West 2 = Array slot 3

I am setting up the 4 resource groups as rg-client-east1, rg-client-east2, rg-client-west1 and rg-client-west2.  everything else is linked to that mapping that i listed above in the arrays

 #region 2 Variables

#Listing of all Resource groups we will create
[array]$RG=@(' ') *4
$RG[0]='rg-client-east1'
$RG[1]='rg-client-east2'
$RG[2]='rg-client-west1'
$RG[3]='rg-client-west2'

#Location for the Resource Groups
[array]$loc=@(' ') *4
$loc[0]='East US'
$loc[1]='East US'
$loc[2]='West US'
$loc[3]='West US'

# Name of each Virtual Networks in each Resource Groups + the BGP ASN Number for each Gateway and the Local Network Gataway Names for each Resource Group
[array]$vnetname=@(' ') *4
[array]$VNetASN=@(' ') *4
[array]$LNGName=@(' ') *4

$vnetname[0]='VNet-client-east1'
$VNetASN[0]=65000
$LNGName[0]='LNG-east1'

$vnetname[1]='VNet-client-east2'
$VNetASN[1]=65010
$LNGName[1]='LNG-east2'

$vnetname[2]='VNet-client-West1'
$VNetASN[2]=65020
$LNGName[2]='LNG-west1'

$vnetname[3]='VNet-client-West2'
$VNetASN[3]=65030
$LNGName[3]='LNG-west2'

#The Address space of each virtual Network
[array]$AddPrefix=@(' ') *4
$AddPrefix[0]='172.25.0.0/20'
$AddPrefix[1]='172.25.16.0/20'
$AddPrefix[2]='172.25.32.0/20'
$AddPrefix[3]='172.25.48.0/20'

#The subnet definition for all subnets
[array]$FeSubnet=@(' ') *4
[array]$BeSubnet=@(' ') *4
[array]$GTWSubnetPrefix=@(' ') *4
$FeSubnet[0]='172.25.0.0/24'
$BeSubnet[0]='172.25.1.0/24'
$GTWsubnetPrefix[0]='172.25.15.0/24'

$BeSubnet[1]='172.25.16.0/24'
$FeSubnet[1]='172.25.17.0/24'
$GTWsubnetPrefix[1]='172.25.31.0/24'

$FeSubnet[2]='172.25.32.0/24'
$BeSubnet[2]='172.25.33.0/24'
$GTWsubnetPrefix[2]='172.25.47.0/24'

$FeSubnet[3]='172.25.48.0/24'
$BeSubnet[3]='172.25.49.0/24'
$GTWsubnetPrefix[3]='172.25.63.0/24'

#the gateway names per sites.
[array]$gatewayname=@(' ') *4
$gatewayname[0]='gw-client-east1'
$gatewayname[1]='gw-client-east2'
$gatewayname[2]='gw-client-west1'
$gatewayname[3]='gw-client-west2'

#the IP configuration variable needed to create the gateway
[array]$gwipconfig=@(' ') *4
$gwipconfig[0]='ip-gw-client-east1-config'
$gwipconfig[1]='ip-gw-client-east2-config'
$gwipconfig[2]='ip-gw-client-West1-config'
$gwipconfig[3]='ip-gw-client-west2-config'

#endregion

 

the BIG change in the creation of the gateways in this example versus the original one is that the New-AzureRmVirtualNetworkGateway command now includes -GatewaySku Standard  -Asn <ASN Number> -EnableBgp $True

When we create the VPN gateway, we now also create an AS number. The ASNs for the connected VNets must be different to enable BGP and transit routing. each VPN gateway must be either:

  • Standard
  • HighPerformance

these are the only ones that support BGP.

 

 #region 4. 
cls

for ($i = 0; $i -le 3; $i++)
{ 
    $Counter=$i.tostring().Trim()

    Write-Host "Setting up Resource Group ", $RG[$i], " In ", $loc[$i],"...."
    $RGNew     = New-AzureRmResourceGroup -Name $RG[$i] -Location $loc[$i]

    Write-Host "Setting up Virtual Network ", $vnetname[$i], " With Sunbnets ", ("FeSubnet$Counter"),("BeSubnet$Counter") ,"...."
    Write-Host "Configuring ", ("FeSubnet$Counter"), " with address ",$FeSubnet[$i]
    $fesub     = New-AzureRmVirtualNetworkSubnetConfig -Name ("FeSubnet$Counter") -AddressPrefix $FeSubnet[$i]

    Write-Host "Configuring ", ("BeSubnet$Counter"), " with address ",$BeSubnet[$i]
    $besub     = New-AzureRmVirtualNetworkSubnetConfig -Name ("BeSubnet$Counter") -AddressPrefix $BeSubnet[$i]

    Write-Host "Configuring GatewaySubnet with address ",$GTWsubnetPrefix[$i]
    $GTWSubnet = New-AzureRmVirtualNetworkSubnetConfig -Name 'GatewaySubnet' -AddressPrefix $GTWsubnetPrefix[$i]

    Write-Host "completing vnet setup of ", $VNetName[$i]
    New-AzureRmVirtualNetwork -Name $VNetName[$i] -ResourceGroupName $RG[$i] -Location $Loc[$i] -AddressPrefix $AddPrefix[$i] -Subnet $fesub,$besub,$GTWSubnet

    Write-Host "Configuring Virtual Network Gateway", $gatewayname[$i],"...."
    $gwpip    = New-AzureRmPublicIpAddress -Name $gatewayname[$i] -ResourceGroupName $RG[$i] -Location $loc[$i] -AllocationMethod Dynamic
    $vnet     = Get-AzureRmVirtualNetwork -Name $VNetName[$i] -ResourceGroupName $RG[$i]
    $GTWsubnet= Get-AzureRmVirtualNetworkSubnetConfig -Name "GatewaySubnet" -VirtualNetwork $vnet
    $gwipconf = New-AzureRmVirtualNetworkGatewayIpConfig -Name $gwipconfig[$i] -Subnet $GTWsubnet -PublicIpAddress $gwpip

    Write-Host "Generating Virtual Network Gateway", $gatewayname[$i],"This may take up to 30 minutes...."
    New-AzureRmVirtualNetworkGateway -Name $gatewayname[$i] -ResourceGroupName $RG[$i] -Location $loc[$i] -IpConfigurations $gwipconf -GatewayType Vpn -VpnType RouteBased -GatewaySku Standard  -Asn $VNetASN[$i] -EnableBgp $True

    $vnetgw[$i] = Get-AzureRmVirtualNetworkGateway -Name $gatewayname[$i] -ResourceGroupName $RG[$i]
}
#endregion

The last step is to create the VPN connections as per our new design. when  creating Site-to-Site VPN connection between your virtual network gateways, the shared key must match the value you used for your VPN device configuration. Note that the -ConnectionType for vnet to vnet must be  -ConnectionType Vnet2Vnet.  if this was a site to site vpn, it would be IPsec.

 #region 5.
# Create vnet to vnet connection as per visio diagram

$RG0='rg-client-east1'
$RG1='rg-client-east2'
$RG2='rg-client-west1'
$RG3='rg-client-west2'

$gatewayname0='gw-client-east1'
$gatewayname1='gw-client-east2'
$gatewayname2='gw-client-west1'
$gatewayname3='gw-client-west2'

#connection 1 - gw-client-east1 to gw-client-west1
$Connectione1W1  = 'east12west1'
$Connectionw1e1  = 'west12east1'

$Connloc1 = 'East US'
$Connloc2 = 'West US'

Write-Host "Collecting Virtual Network Gateway information...."
$vnet1gw = Get-AzureRmVirtualNetworkGateway -Name $gatewayname0 -ResourceGroupName $RG0
$vnet2gw = Get-AzureRmVirtualNetworkGateway -Name $gatewayname2 -ResourceGroupName $RG2

Write-Host "Creating reciprocal connections between ", $gatewayname0, " and ", $gatewayname2," ...."
New-AzureRmVirtualNetworkGatewayConnection -Name $Connectione1W1 -ResourceGroupName $RG0 -VirtualNetworkGateway1 $vnet1gw -VirtualNetworkGateway2 $vnet2gw -Location $Connloc1 -ConnectionType Vnet2Vnet -SharedKey 'AzureA1b2C3' -EnableBgp $true
New-AzureRmVirtualNetworkGatewayConnection -Name $Connectionw1e1 -ResourceGroupName $RG2 -VirtualNetworkGateway1 $vnet2gw -VirtualNetworkGateway2 $vnet1gw -Location $Connloc2 -ConnectionType Vnet2Vnet -SharedKey 'AzureA1b2C3' -EnableBgp $true

#connection 2 - gw-client-east1 to gw-client-east2
$Connectione1W1  = 'east12east2'
$Connectionw1e1  = 'east22east1'

$Connloc1 = 'East US'
$Connloc2 = 'East US'

Write-Host "Collecting Virtual Network Gateway information...."
$vnet1gw = Get-AzureRmVirtualNetworkGateway -Name $gatewayname0 -ResourceGroupName $RG0
$vnet2gw = Get-AzureRmVirtualNetworkGateway -Name $gatewayname1 -ResourceGroupName $RG1

Write-Host "Creating reciprocal connections between ", $gatewayname0, " and ", $gatewayname1," ...."
New-AzureRmVirtualNetworkGatewayConnection -Name $Connectione1W1 -ResourceGroupName $RG0 -VirtualNetworkGateway1 $vnet1gw -VirtualNetworkGateway2 $vnet2gw -Location $Connloc1 -ConnectionType Vnet2Vnet -SharedKey 'AzureA1b2C3' -EnableBgp $true
New-AzureRmVirtualNetworkGatewayConnection -Name $Connectionw1e1 -ResourceGroupName $RG2 -VirtualNetworkGateway1 $vnet2gw -VirtualNetworkGateway2 $vnet1gw -Location $Connloc2 -ConnectionType Vnet2Vnet -SharedKey 'AzureA1b2C3' -EnableBgp $true

#connection 1 - gw-client-West1 to gw-client-West2
$Connectione1W1  = 'west12west2'
$Connectionw1e1  = 'west22west1'

$Connloc1 = 'West US'
$Connloc2 = 'West US'

Write-Host "Collecting Virtual Network Gateway information...."
$vnet1gw = Get-AzureRmVirtualNetworkGateway -Name $gatewayname2 -ResourceGroupName $RG2
$vnet2gw = Get-AzureRmVirtualNetworkGateway -Name $gatewayname3 -ResourceGroupName $RG3

Write-Host "Creating reciprocal connections between ", $gatewayname2, " and ", $gatewayname3," ...."
New-AzureRmVirtualNetworkGatewayConnection -Name $Connectione1W1 -ResourceGroupName $RG2 -VirtualNetworkGateway1 $vnet1gw -VirtualNetworkGateway2 $vnet2gw -Location $Connloc2 -ConnectionType Vnet2Vnet -SharedKey 'AzureA1b2C3' -EnableBgp $true
New-AzureRmVirtualNetworkGatewayConnection -Name $Connectionw1e1 -ResourceGroupName $RG3 -VirtualNetworkGateway1 $vnet2gw -VirtualNetworkGateway2 $vnet1gw -Location $Connloc2 -ConnectionType Vnet2Vnet -SharedKey 'AzureA1b2C3' -EnableBgp $true

#endregion

 

This script will take a long time to run considering that each gateway creation can take up to 30 minutes.  However once all the connections we will have transitive routes end to end.

I created 4 VMs. One in each site.

image

Because of the BGP configurations of our new gateways they actually learn the routing tables of each other gateways allowing us to be able to communicate from the East 2 site to the west 2 site through east 1 and west 1.

image

 

image

 

So there you go.  a fully routed network with the elegance of a simple and manageable design.

I hope this is a useful post.

Cheers!

Signature

Pierre Roman
@pierreroman