This article covers a very common use case for startups using Microsoft Azure and BizSpark: how to connect virtual machines from two virtual networks in different subscriptions (or regions) with the new Azure Portal (Resource Manager or ARM).

The BizSpark program gives startups like Savelist free Azure credits for up to 3 years. The catch is that these credits are divided in several subscriptions with $150/€130 each (one per team member). In order to get the most out of the BizSpark credits, you’ll want to use more than one subscription, but all the resources you create are bound to that subscription. The easiest (note I didn’t write easy) way is to connect the virtual networks through a VPN at the infrastructure level, using what Azure calls Virtual Network Gateways.

So to be clear, this article supposes that:

  • Your VMs and virtual networks were created in the new Azure Portal(Resource Manager mode or ARM), not the old Classic Portal (Service Manager mode or ASM) .
  • These VMs are in different virtual networks. It doesn’t matter if they are in the same subscription, in other subscription or in another Azure location. We’ll connect them with a secure VPN that will route the traffic over the Internet (but inside the Azure backbone). If they are in the same virtual network, the VMs will just see each other and you don’t need any of this.
  • You want to use the Azure Portal instead of the Azure CLI or PowerShell. Because we are cool dev hipsters, not SysAdmins from the 90s (although the Azure CLI is wrote in NodeJS and that’s also cool).

Requirements

Before we can connect the virtual networks, there are some requirements and considerations:

  • The address spaces of the virtual networks cannot collide. If they did, when a VM wanted to connect to a local IP, the virtual network wouldn’t know how to route this request.
  • We will need to create two Virtual Network Gateways, one for each network. These cost around $27/€23 a piece (in March 2016).
  • You may also have to pay for outbound data traffic sent between the networks if they are in different regions or outside of Azure, as the VPN connection will be established using public IPs, and therefore routed through the Internet. You won’t be charged twice, as inbound traffic is always free.

Deployment Overview

These are all the resources we will use. I’ll be using the letters a and b to refer to each side of the connection. You can name them whatever you want but I recommend writing your equivalent in a cheat sheet:

  • 2 existing Virtual Networks: network-a and network-b.
  • 2 or more existing Subnets: subnet-a and subnet-b, inside network-a and network-b, respectively.
  • 2 new Virtual Network Gateways: vpn-gateway-a and vpn-gateway-b.
  • 2 new Public IP addresses for the Virtual Network Gateways: vpn-ip-a and vpn-ip-b.
  • 2 new Local Network Gateways: local-gateway-a and local-gateway-b.
  • 2 new Connections: vpn-connection-a and vpn-connection-b.

In the example I will be also considering that you have 2 different subscriptions, resource groups and locations.

If you have your virtual networks under the same subscription, resource group or location it’s okay, just consider that the following are the same in your case.
  • iptions: subscription-a and subscription-b (can be the same).
  • 2 Resource Groups: resource-group-a and resource-group-b (can be the same).
  • 2 Locations: location-a and location-b (can be the same).

Network Specs

These are the specs of the two networks. Notice that the IP address spaces are different, so they don’t collide. If they do now, you will have to change the address space in one of them before you continue.

network-a
  Address space: 10.0.0.0/16
  Subnets:
    subnet-a: 10.0.0.0/24
network-b
  Address space: 10.1.0.0/16
  Subnets:
    subnet-b: 10.1.0.0/24

1. Create the Gateway Subnets

The Virtual Network Gateways that we will create in the next step need that the networks have a special subnet inside exactly named GatewaySubnet. If you already have them just skip this step.

Go to Virtual networks > Settings > Subnets and click the add Gateway subnet button. Choose an address space inside network-a that is bigger or equal to /29 and that doesn’t collide with the other subnets. For simplicity, I’m using /24. Repeat the steps with network-b so you end up with something like this:

network-a
  Address space: 10.0.0.0/16
  Subnets:
    subnet-a: 10.0.0.0/24
    GatewaySubnet: 10.0.1.0/24
network-b
  Address space: 10.1.0.0/16
  Subnets:
    subnet-b: 10.1.0.0/24
    GatewaySubnet: 10.1.1.0/24

2. Create the Virtual Network Gateways

Go to Virtual network gateways > Add and select the following:

Name: vpn-gateway-a
Virtual network: network-a
Public IP address: vpn-ip-a (new)
Gateway type: VPN
VPN type: Route-based
Subscription: subscription-a
Resource group: resource-group-a
Location: location-a

Repeat the steps for the other subscription/network:

Name: vpn-gateway-b
Virtual network: network-b
Public IP address: vpn-ip-b (new)
Gateway type: VPN
VPN type: Route-based
Subscription: subscription-b
Resource group: resource-group-b
Location: location-b

The deploy can take up to 45 minutes, but we can set some other things up meanwhile.

3. Find the IP addresses

When the deploy of the previous step starts, you will have 2 new public IP addresses, vpn-ip-a and vpn-ip-b. It’s okay if the Virtual Network gateways are still deploying because the IPs are created at the beginning. If there aren’t there just wait a couple of minutes and refresh the list.

Go to Public IP addresses, select vpn-ip-a and write down its number because we will need it later on. Do the same for vpn-ip-b. Let’s say these are my public IPs (yours will be different):

vpn-ip-a: 40.84.0.1
vpn-ip-b: 40.84.0.2

4. Create the Local Network Gateways

This is the tricky part that took me a couple of hours to figure out. In each side of the VPN, we have a virtual network with a virtual gateway (probably still deploying) that acts as a door to the outside Internet that sends and receives traffic to the other end. But we need something to tell our virtual network “hey, for these local IP address outside your address space, you will have to get them through the door at 40.84.0.X”.

So network-a needs to know that the 10.1.0.0/16 range, that is outside its address space (10.0.0.0/16), is reachable through vpn-ip-b (40.84.0.2). And network-b (10.1.0.0/16) needs to know that the outside space 10.0.0.0/16 is reachable through vpn-ip-a (40.84.0.1). This something is a Local Network Gateway.

Go to Local network gateways > Add and create one for network-a:

Name: local-gateway-b
IP address: 40.84.0.2 (vpn-ip-b)
Address space: 10.1.0.0/16
Subscription: subscription-a
Resource group: resource-group-a
Location: location-a

See what happened here? We created the local-gateway-b in the same subscription and resource group as network-a, with the public IP and address space of network-b. This is how network-a knows how to get to an IP from network-b.

Let’s now create the one for network-b:

Name: local-gateway-a
IP address: 40.84.0.1 (vpn-ip-a)
Address space: 10.0.0.0/16
Subscription: subscription-b
Resource group: resource-group-b
Location: location-b

5. Create the Connections

From this point forward you need both Virtual Network Gateways to have finished deploying. If they haven’t, just chill out or have a look at what we do at Savelist.

With the Virtual Network Gateways deployed, we now need to create a connection between local-gateway-b and vpn-gateway-a (for network-a) and another between local-gateway-a and vpn-gateway-b (for network-b). This will complete the traffic routing.

   network-a
local-gateway-b
 vpn-gateway-a
      ||
   Internet
      ||
 vpn-network-b
local-gateway-a
  network-b

Go to Local network gateways in subscription-a and select local-gateway-band then Settings > Connections > Add. The Connection type will already have Site-to-site (IPsec) selected and greyed out.

You can choose any mix of letters and numbers as your shared key (PSK), as long as you put the same in both vpn-connection-a and vpn-connection-b. It acts as a password to secure the connection.

Pro tip: The GRC site generates ultra secure passwords just for you through HTTPS. I copied and pasted the one in the 3rd box.
Name: vpn-connection-b
Connection type: Site-to-site (IPsec)
Virtual network gateway: vpn-gateway-a
Local network gateway: local-gateway-b (locked)
Shared key (PSK): (choose a mix of letters and numbers)
Subscription: subscription-a
Location: location-a

Repeat the process for local-gateway-a in subscription-b:

Name: vpn-connection-a
Connection type: Site-to-site (IPsec)
Virtual network gateway: vpn-gateway-b
Local network gateway: local-gateway-a (locked)
Shared key (PSK): (paste the same key as before)
Subscription: subscription-b
Location: location-b

If everything went well, after a few minutes the Virtual Networks Gateways will establish a connection and show with the Connected status. If it doesn’t work after 10 minutes, check that the IPs and address spaces in the Local Network Gateways are correct and from the other network.

6. Test the Connection

You can just now log into a machine in network-a and try to access a machine in network-b, and viceversa. You will see the traffic increase in the connection details. If it doesn’t work, check the network security groups used by your virtual machines and/or virtual networks. If the VPN connection shows Connected, then is working fine and something else in your networks is blocking the communication.


Special thanks to Jesús Huerta, who helped me translate the old and confusing articles from Microsoft to the newer Azure Portal and ARM.