HOW-TO: Building V2 VNET-to-VNET Connections with Azure Resource Manager and PowerShell in 5 Steps

As a follow-up to my original End-to-End IaaS scenario using Azure Resource Manager (ARM), PowerShell and DSC, this article expands our configuration to include a VNET-to-VNET connection between Azure Virtual Networks provisioned via the new v2 ARM stack.

VNET-to-VNET scenario

VNET-to-VNET connections are useful for peering individual VNETs that may exist in separate Azure datacenter regions or subscriptions. To learn more about the advantages and usage scenarios for VNET-to-VNET connections, be sure to read the article linked below.

Now, let’s get started ...

1. Getting Started

Before configuring VNET-to-VNET connectivity, we’ll need to make sure that Azure PowerShell and our Azure subscription are prepared.  Be sure to follow Steps 1 through 8 in my original article to perform the necessary Getting Started steps and then come back to this article to continue the process.

As of the publishing date of this article, only a subset of Azure datacenter regions support Azure Virtual Network Gateways and VNET-to-VNET Connections, so be sure to double check that you’ve selected an Azure datacenter region in Step 7 of the steps linked above that includes support for “Microsoft.Network/virtualNetworkGateways” and “Microsoft.Network/connections” resource types.  Over time, support for these resource types will be extended broadly to all Azure datacenter regions.

2. Create Virtual Networks

In this step, we’ll create two Virtual Networks – VNET1 and VNET2 – that will host the appropriate IP address spaces and subnets that we wish to connect.  In later steps, we’ll add Virtual Network Gateways to the “GatewaySubnet” on each VNET for establishing the VNET-to-VNET connection.

# Create VNET1, if it doesn't already exist

$vnet1Name = "${prefix}-vnet1"

$subnet1Name = "${prefix}-subnet1"

$subnet2Name = "GatewaySubnet"

if (!(Test-AzureResource `
-ResourceName $vnet1Name `
-ResourceType "Microsoft.Network/virtualNetworks" `
-ResourceGroupName $rgName)) {

    # Create VNET1

$subnet1 = New-AzureVirtualNetworkSubnetConfig `
-Name $subnet1Name `
-AddressPrefix "10.0.1.0/24"

    $subnet2 = New-AzureVirtualNetworkSubnetConfig `
-Name $subnet2Name `
-AddressPrefix "10.0.2.0/28"

    $vnet1 = New-AzureVirtualNetwork `
-Name $vnet1Name `
-ResourceGroupName $rgName `
-Location $location `
-AddressPrefix "10.0.0.0/16" `
-Subnet $subnet1, $subnet2 `
-Tag $tags

} else {

    # Get VNET1 configuration

$vnet1 = Get-AzureVirtualNetwork `
-Name $vnet1Name `
-ResourceGroupName $rgName

}

# Create VNET2, if it doesn't already exist

$vnet2Name = "${prefix}-vnet2"

$subnet1Name = "${prefix}-subnet1"

$subnet2Name = "GatewaySubnet"

if (!(Test-AzureResource `
-ResourceName $vnet2Name `
-ResourceType "Microsoft.Network/virtualNetworks" `
-ResourceGroupName $rgName)) {

    # Create VNET2

$subnet1 = New-AzureVirtualNetworkSubnetConfig `
-Name $subnet1Name `
-AddressPrefix "10.1.1.0/24"

    $subnet2 = New-AzureVirtualNetworkSubnetConfig `
-Name $subnet2Name `
-AddressPrefix "10.1.2.0/28"

    $vnet2 = New-AzureVirtualNetwork `
-Name $vnet2Name `
-ResourceGroupName $rgName `
-Location $location `
-AddressPrefix "10.1.0.0/16" `
-Subnet $subnet1, $subnet2 `
-Tag $tags

} else {

    # Get VNET2 configuration

    $vnet2 = Get-AzureVirtualNetwork `
-Name $vnet2Name `
-ResourceGroupName $rgName

}

3. Register Public IPs for VNET Gateways

Each Virtual Network Gateway that we’ll be provisioning will require a public IP address to be able to communicate between VNETs.  In this step, we’ll register two public IP addresses that we’ll use for configuring the IP properties of the VNET gateway in later steps.

# Register a Public IP for VNET1 Gateway

$vnet1GatewayName = "${prefix}-gw1"

$vnet1PublicGatewayVipName = "${prefix}-gw1vip"

if (!(Test-AzureResource `
-ResourceName $vnet1PublicGatewayVipName `
-ResourceType "Microsoft.Network/publicIPAddresses" `
-ResourceGroupName $rgName)) {

    # Create Public IP for VNET1 Gateway

$vnet1PublicGatewayVip = New-AzurePublicIpAddress `
-Name $vnet1PublicGatewayVipName `
-ResourceGroupName $rgName `
-Location $location `
-AllocationMethod Dynamic `
-DomainNameLabel $vnet1GatewayName `
-Tag $tags

} else {

    # Get Public IP for VNET1 Gateway

    $vnet1PublicGatewayVip = Get-AzurePublicIpAddress `
-Name $vnet1PublicGatewayVipName `
-ResourceGroupName $rgName

}

# Register a Public IP for VNET2 Gateway

$vnet2GatewayName = "${prefix}-gw2"

$vnet2PublicGatewayVipName = "${prefix}-gw2vip"

if (!(Test-AzureResource `
-ResourceName $vnet2PublicGatewayVipName `
-ResourceType "Microsoft.Network/publicIPAddresses" `
-ResourceGroupName $rgName)) {

    # Create Public IP for VNET2 Gateway

    $vnet2PublicGatewayVip = New-AzurePublicIpAddress `
-Name $vnet2PublicGatewayVipName `
-ResourceGroupName $rgName `
-Location $location `
-AllocationMethod Dynamic `
-DomainNameLabel $vnet2GatewayName `
-Tag $tags

} else {

    # Get Public IP for VNET2 Gateway

    $vnet2PublicGatewayVip = Get-AzurePublicIpAddress `
-Name $vnet2PublicGatewayVipName `
-ResourceGroupName $rgName

}

4. Create VNET Gateways

Now that we have a Public IP Address reserved for each Virtual Network Gateway, we’re ready to provision the Gateways.  As we’re creating each Gateway, we’ll attach them to the appropriate Public IP Address on the front-end side of each Gateway. and we’ll also attach them to the respective VNET, Subnet and Private IP Address for back-end connectivity between each Gateway and its associated Virtual Network.

# Create VNET1 Gateway if it doesn't exist

if (!(Test-AzureResource `
-ResourceName $vnet1GatewayName `
-ResourceType "Microsoft.Network/virtualNetworkGateways" `
-ResourceGroupName $rgName)) {

    # Create IP Config to attach VNET1 Gateway to VIP & Subnet

    $vnet1GatewayIpConfigName = "${prefix}-gw1ip"

    $vnet1GatewayIpConfig = `
New-AzureVirtualNetworkGatewayIpConfig `
-Name $vnet1GatewayIpConfigName `
-PublicIpAddressId $vnet1PublicGatewayVip.Id `
-PrivateIpAddress "10.0.2.4" `
-SubnetId $vnet1.Subnets[1].Id

    # Provision VNET1 Gateway

    $vnet1Gateway = New-AzureVirtualNetworkGateway `
-Name $vnet1GatewayName `
-ResourceGroupName $rgName `
-Location $location `
-GatewayType Vpn `
-VpnType RouteBased `
-IpConfigurations $vnet1GatewayIpConfig `
-Tag $tags

} else {

# Get current config of VNET1 Gateway

    $vnet1Gateway = Get-AzureVirtualNetworkGateway `
-Name $vnet1GatewayName `
-ResourceGroupName $rgName

}

# Create VNET2 Gateway if it doesn't exist

if (!(Test-AzureResource `
-ResourceName $vnet2GatewayName `
-ResourceType "Microsoft.Network/virtualNetworkGateways" `
-ResourceGroupName $rgName)) {

    # Create IP Config to attach VNET2 Gateway to VIP & Subnet

    $vnet2GatewayIpConfigName = "${prefix}-gw2ip"

    $vnet2GatewayIpConfig = `
New-AzureVirtualNetworkGatewayIpConfig `
-Name $vnet2GatewayIpConfigName `
-PublicIpAddressId $vnet2PublicGatewayVip.Id `
-PrivateIpAddress "10.1.2.4" `
-SubnetId $vnet2.Subnets[1].Id

    # Provision VNET2 Gateway

    $vnet2Gateway = New-AzureVirtualNetworkGateway `
-Name $vnet2GatewayName `
-ResourceGroupName $rgName `
-Location $location `
-GatewayType Vpn `
-VpnType RouteBased `
-IpConfigurations $vnet2GatewayIpConfig `
-Tag $tags

} else {

    # Get current config of VNET2 Gateway

    $vnet2Gateway = Get-AzureVirtualNetworkGateway `
-Name $vnet2GatewayName `
-ResourceGroupName $rgName

}

5. Create VNET-to-VNET Connections

The last step in configuring VNET-to-VNET connectivity is to create the connections from each VNET Gateway to the Gateway on the opposite VNET.  In this step, we’ll create two VNET connections to complete our process: one connection from VNET1-to-VNET2, and one connection from VNET2-to-VNET1.

# Create VNET1-to-VNET2 connection, if it doesn't exist

$vnet12ConnectionName = "${prefix}-vnet-1-to-2-con"

if (!(Test-AzureResource `
-ResourceName $vnet12ConnectionName `
-ResourceType "Microsoft.Network/connections" `
-ResourceGroupName $rgName)) {

    $vnet12Connection = `
New-AzureVirtualNetworkGatewayConnection `
-Name $vnet12ConnectionName `
-ResourceGroupName $rgName `
-Location $location `
-ConnectionType Vnet2Vnet `
-Tag $tags `
-VirtualNetworkGateway1 $vnet1Gateway `
-VirtualNetworkGateway2 $vnet2Gateway

} else {

    # Get Azure VNET1-to-VNET2 connection

$vnet12Connection = `
Get-AzureVirtualNetworkGatewayConnection `
-Name $vnet12ConnectionName `
-ResourceGroupName $rgName

}

# Create VNET2-to-VNET1 connection, if it doesn't exist

$vnet21ConnectionName = "${prefix}-vnet-2-to-1-con"

if (!(Test-AzureResource `
-ResourceName $vnet21ConnectionName `
-ResourceType "Microsoft.Network/connections" `
-ResourceGroupName $rgName)) {

    # Get VNET Connection Shared Key

    $vnetConnectionKey = `
Get-AzureVirtualNetworkGatewayConnectionSharedKey `
-Name $vnet12ConnectionName `
-ResourceGroupName $rgName

    # Establish VNET2-to-VNET1 connection

    $vnet21ConnectionName = "${prefix}-vnet-2-to-1-con"

    $vnet21Connection = `
New-AzureVirtualNetworkGatewayConnection `
-Name $vnet21ConnectionName `
-ResourceGroupName $rgName `
-Location $location `
-ConnectionType Vnet2Vnet `
-SharedKey $vnetConnectionKey `
-Tag $tags `
-VirtualNetworkGateway1 $vnet2Gateway `
-VirtualNetworkGateway2 $vnet1Gateway

} else {

    # Get Azure VNET2-to-VNET1 connection

$vnet21Connection = `
Get-AzureVirtualNetworkGatewayConnection `
-Name $vnet21ConnectionName `
-ResourceGroupName $rgName

}

Completed! What's Next?

Now that your V2 VNET-to-VNET configuration is complete, you're ready to provision the VMs that will need to communicate across the connection.  When provisioning VMs, be sure to select the appropriate VNET and Subnet for each. Also, if you're using Network Security Groups or an OS-level firewall inside each VM, you'll want to verify that appropriate network traffic is permitted between the VMs in VNET1 and VNET2.

See you in the Clouds!

- Keith