Azure VNET to VNET VPN, across regions and data centers: not so complicated

After finding very interesting articles like this one (thanks, Matt Davies) around recently announced features on Azure, I wanted to push further the IaaS  experience on Microsoft’s public cloud by connecting multiple Azure virtual networks simultaneously, eventually across data centers. The utilization of this functionality becomes quickly interesting in various scenarios, like geo-highly available applications and disaster recovery plans.

So here is my scenario: let’s say we need 1 VNET in North Europe region (Dublin) to be connected to a second VNET  in the same datacenter and to a third one in West Europe (Amsterdam). We will test the result simply by pinging between 3 VMs, one in each VNET.


Assumption: in order to keep this article to a reasonable size, I assume you are somehow familiar already with the main (Azure) IaaS concepts (VNET, VPN, VM, Local Network …).

First things first, let’s plan & design:
  • Let’s name our VNETs as “net1dublin”, “net2dublin” and “net3amsterdam
  • Each of them will need to have mutually exclusive IP ranges, so we will choose in order:
    • for net1dublin,
    • for net2dublin, and
    • for net3amsterdam
(which means we have reserved 8 bits = maximum 256 IP addresses for each network).
  • Each VNET will have activated the “site-to-site” VPN functionality. As per VPN requirements, each VNET  will have 1 subnet dedicated to the public gateway, plus at least 1 subnet for the real usage (VMs)
  • Each VNET will be exposed to the other ones as a “local” network (in the Azure sense). We will name that as “remote1dublin”, “remote2dublin”, and “remote3amsterdam”.
  • The VPN device IP address will correspond to each VPN public gateway. The VNET public gateway will be generated only after the VPN itself  is created; hence, we won’t have a public IP to fill in at the creation of its corresponding local network.

    We will create the local networks with fake IPs at the beginning; then we will update them later with the real ones after the generation of the gateways.

    Also, important: we will fill in strictly the same IP address space in the VNET and its corresponding local network.
Now, let’s go to work, to see what that means.
We will create first the local networks (put something like as device IP):
Then we specify the address space (as planned) and save it.
We do the same thing for each of the 3 local networks.
Now let’s create the first virtual network: net1dublin.
We will activate the site-to-site VPN feature. We will select remote2dublin as the “local” network to connect with.
(note: for brevity, the DNS info will not be filled in here)
The VNET address space is filled in as planned. In this case, 1 unique subnet for the VM(s) and one subnet for the gateway.
So, the VNET is created; now we will create – for our purpose specifically – a Dynamic Routing Gateway.
The gateway will be created…
… in about 15-20 min (it takes longer than a VM creation).
Note that the networks are still disconnected. This is because:
1.  We didn’t update the gateway IP addresses in the Local Networks records. Let’s do it now (replace the values with the gateways public IPs):
2. The networks are not secured via IPSEC channel. We need to set a unique shared key for both gateways. You may choose your own key value; the important thing is to set the same value on both sides.
As of today this cannot be done via portal, only via PowerShell (or CLI):
Set-AzureVNetGatewayKey -VNetName net1dublin -LocalNetworksiteName remote2dublin -sharedKey abcdefgh1234
Set-AzureVNetGatewayKey -VNetName net2dublin -LocalNetworksiteName remote1dublin -sharedKey abcdefgh1234
Here is the console output:
And… That’s it!  (for the first half of work :) )

Let’s test what we have done until now:
  • create at least one VM in each of 2 virtual networks (no matter the size, image etc.)
  • RDP to the 2 VMs
  • Open each of the OS firewalls for “echo” service (or temporarily turn them off)
  • Execute “ipconfig” commands, to get the IP for each of the VMs
  • Execute “ping” commands to each other. Shortly you should see them nicely communicate over VPN:
    (screenshot from the VM in “net1dublin” VNET)
(screenshot from the VM in “net2dublin” VNET)
Under the VNET dashboard, we may see also the data exchange over the network:
image  (and similarly in the VNET 2)

Cool, isn’t it?…

Now, let’s move on to the next part.
Let’s not forget our goal which is, connect 3 VNETs.
First, let’s create the 3rd record for the “Local Network”, this one in Amsterdam region (West Europe):
Now let’s create the 3rd VNET, “net3amsterdam”. We will also configure a site-to-site VPN to “net1dublin”:
Everything looks good:
But remember that the relationship must be bidirectional. Right now “net1dublin” is only related to “net2dublin”.
As of today, in the Azure portal you cannot associate 2 local networks simultaneously to a site-to-site VPN (there is only one listbox there, remember?).
No problem, we will do it other ways – by exporting and reimporting the Azure network configuration file.
WARNING: the network configuration file represents the network configuration for the whole Azure subscription. When (re)importing it, you may alter (by error) configurations for other networks aside in the same subscription, if any. Manipulate the content of  this file carefully if you want to import it into your subscription!
Now, first, we export the network configuration from the portal. It is a single XML file for the whole subscription:
In the file, look for the virtual network node (“net1dublin”), then look for the “ConnectionsToLocalNetwork” node and add a child node corresponding to the new record:
            <LocalNetworkSiteRef name="remote2dublin">
              <Connection type="IPsec" />
            <LocalNetworkSiteRef name="remote3amsterdam">
              <Connection type="IPsec" />

Here is the whole XML node after editing:
Then we import the configuration back in Azure:
We will select the modified network config file – on the good subscription (obviously :) ):
You may see that some of the networks are marked as being updated when importing:
(note: you may remark that the 3 VNETs are marked as updated, which is not correct – we only changed the VNET 1; I believe it is a wrong reporting of the UI.
Actually, you can see below that only the first VNET is updating – which comforts me :) )
After updating ended, let’s look of the status of the network:
Funny thing, the nice drawing is replaced by a table listing the 2 VNETs associated (of which, the 2nd is not connected yet).
Even funnier, you may realize that, even if the UI doesn’t let you to associate a second VNET, it will know to display it, if created otherwise.
What’s next ? The IPSEC shared key.
We will proceed as we did before. We have the possibility to set a different / specific key for this particular association:
Set-AzureVNetGatewayKey -VNetName net1dublin -LocalNetworksiteName remote3amsterdam -sharedKey ijklmn5678
Set-AzureVNetGatewayKey -VNetName net3amsterdam -LocalNetworksiteName remote1dublin -sharedKey ijklmn5678

Here is the result:
And… that’s really it, now. We’re done.

The proof  is here – a ping from a VM in Dublin, to a VM created in Amsterdam :)
…and the vice versa:
And 2 other nice screenshots, showing us the perfect communication between the 2 European Azure data centers : ) :
Now that’s cool!

2-3 more remarks, if you look again at the last console output:
  • How do we know the VMs are in 2 different datacenters? Look at the ping response time, it is a bit longer :) (though it’s still remarkable as performance, knowing they are at over 700 kilometers distance)
  • While the ping from to works well, you may see that the ping from to timed out. Which proves that the VPN connection is strictly limited to what we have asked: VNET1 to VNET2 and VNET1 to VNET3. Of course, we could continue in the same way and VPN 2 with 3 (or, other option,  extending the routing in VNET1?)
  • Today, I didn’t create VPN over different Azure subscriptions. Not possible actually via the portal. But we already know this shouldn’t stop doing things, right?….
I hope you have enjoyed the article, see you next time :)

1 commentaire:

  1. Thanks a lot for the blogpost. it was very informative, especially the part about export and importing the NW config. Kind of a strange thing this azure portal, isnt it?