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… )
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:
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.
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.
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.
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!
Pierre Roman
@pierreroman
Comments
- Anonymous
December 13, 2016
Fantastic post! Thank you.