Three years ago, I was working with a customer that wanted to connect their VPC on AWS to their virtual network in Azure so they could move data around and migrate some workloads.
Lately I’ve been receiving some messages from folks all over the place (some internal and some external to Microsoft) about issues in setting up that type of connection between AWS and Azure. I figured, it’s three years old…. There is bound to be some components that’s changed so maybe I should take another look at it.
I really used a very similar approach. And the same basic test architecture.
As before I will show you how I created that site to site IPsec tunnel to connect to a Virtual Private Cloud (VPC) hosted in Amazon Web Services (AWS) to a Virtual Network in Azure.
In our case we selected a Windows 2012 R2 server as the end point of the tunnel on the AWS side mostly because it is a supported platform as a Azure VPN device for route-based VPN that did not add costs to our POC unlike other supported virtual appliances from the AWS marketplace that are supported as validated VPN devices on Azure.
It would be very clean if we could just connect the AWS Gateway with the Azure Virtual Network Gateway. However, there are a few problems.
- First, the Azure VPN Gateway can act as either initiator or responder of the tunnels, but AWS VGW can only act as a responder, Azure endpoint would have to be the initiator at all times.
- Second, as per Azure documentation, when Azure VPN Gateway acts as the initiator, Perfect Forward Secrecy (PFS) is not enabled for phase 2. AWS end requires PFS to be enabled for the tunnels to come up
- Third, Azure uses IKEv1 for policy-based VPNs and IKEv2 for route-based VPNs. AWS supports only IKEv1 at this point of time.
- Finally, there is a mismatch in the phase 2 lifetimes also. Azure use a phase 2 lifetime of 3600s for policy-based VPNs and 27000s for route-based VPNs. AWS uses a phase 2 lifetime of 3600s only
- Therefore, one side must use an appliance or some kind of virtual edge device.
Let’s prepare the Azure side of the equation to start.
I started by creating a Virtual Network called AZR-Vnet in the AZR-AWS resource group. With the following parameters:
- Address Space 172.16.0.0/16
- 1 subnet called “FrontEnd” with an address space of 172.16.0.0/24
Once the Vnet was created I create the “Gateway Subnet” needed by the Azure VPN gateway. In the vnet configuration under (1) Subnet I only had to click the “+ Gateway Subnet”
When providing the subnet name ensure that you use “GatewaySubnet” (This name is mandatory for Gateway Subnets). We used the subnet address space – 172.16.254.0/24
At this point I deployed 2 VM on the network. One Windows 2019 DC and one Linux box.
- Install domain services and DNS on this server and Promote the Windows machine to a DC
- Set Vnet DNS setting to use the Windows DC as the vnet DNS
Now I have to configure the AWS side of the setup. First, I created an Elastic IP in AWS
I need to an allocate an address in AWS. It will be assigned in later steps to the AWS VPN gateway. However, we will need that IP address before we start configuring the Azure VPN gateway.
In the VPC dashboard, click Elastic IPs, allocate New Address and click Yes, Allocate
Then select the Amazon Pool, and click Allocate.
Make sure to Note the IP address so we can use it when we setup the Azure VPN gateway.
Next, I created a new VPC.
- Name Aws-Vnet
- Address block of 10.0.0.0/16
- I used the following name: frontend
- CIDR: 10.0.1.0/24
Once the VPC creation completed, I wantd to confirm that my VPC is connected to and internet Gateway.
At this point I also deployed 2 VM on the VPC one DC that will sync with the DC in Azure and sync DNS zone and one Linux box.
At this point having a VPC up and running we created an EC2 instance in the VPC that will act as our edge VPN device. There are many supported devices listed in the “Validated VPN devices and device configuration guides” in our Documentation which can be found here. https://aka.ms/AZRVPNDevice. I am using a Windows Server 2012 R2 instance here since it’s a temporary test. Using a real hardened edge device is recommended. When launching the instance, make sure that Auto-assign Public IP is enabled.
Once it’s created, I went to the network interface and noted the Network Interface ID for the instance we just created, and you can edit the Name if you want to make it easier to find later.
Once the instance is running, I associated the “Elastic IP” we created earlier to the Network interface of the instance. By clicking Elastic IPs in the VPC dashboard, selecting Associate Address in the action menu, selecting the Network interface used by the Windows Server 2012 R2 instance we created earlier and click associate
Next, disable source/destination checking on the server.
EC2 instances always performs Source/Dest checks to ensure that the instance is the source or destination of any traffic it sends or receives.
However, a NAT instance or an instance that will be routing traffic must disable source/destination checks on the that instance.
Ok. The base infrastructure is ready.
Let’s jump in the Gateway creation. In Azure, I create a new Virtual Network Gateway with the name AWS-AZR-GTW connected to the Vnet I created earlier in the GatewaySubnet I created.
After the gateway has been created, I will need to note the IP Address of the Virtual network Gateway since I will need it later.
Then, navigate back to the Resource Group and Add a “Local Network Gateway”.
The local network gateway typically refers to your on-premises location. You give the site a name by which Azure can refer to it, then specify the IP address of the on-premises VPN device (or in my case the AWS device) to which you will create a connection.
You also specify the IP address space that will be routed through the VPN gateway to the VPN device. The address space you specify are the prefixes located on your on-premises network. If your AWS network changes or you need to change the public IP address for the VPN device, you can easily update the values later.
In the next blade, fill the information of the AWS VPC (IP address is the Elastic IP assigned to the GTW we created earlier and address space of the VPC CIDR in AWS)
Ensure that you are always selecting the right Resource Group in our case AZR-AWS and click create
Wait for the Local network Gateway to be created. Once it is created, in the settings of the local network gateway, in the connections setting, add a new connection.
In the connection settings give it a name select the Azure Virtual network gateway we created earlier and supply a shared key. In my case the sharedvb secret is “}7xpcZoUzbjP4r!eJ4Vr”
- note the shared key, you will need it later. please generate a strong shared key. I used my Password Manager to generate a random password with 20 characters (number, letters and symbols).
And I now have both environments ready. All I need is to configure my AWS Windows Server 2012 R2 edge device.
I started out with the “Microsoft-rras-windows-server-2012-r2.ps1.xslt” script in a Github repo (https://github.com/Azure/Azure-vpn-config-samples) under the Microsoft folder.
However, I started getting errors when running the script. So, I simplified things to get it running quickly. At some point I’ll figure out the issue with the script and make a Pull Request. But tonight, I don’t have the time.
So, I installed the Remote Access, the DirectAccess & VPN and the routing role manually on the Windows 2012 R2 box.
And then ran a modified version on the script that I’ve included below. I’m highlighting in yellow the parts you would need to modify.
# Windows Azure Virtual Network
# Install S2S VPN
if ((Get-RemoteAccess).VpnS2SStatus -ne “Installed”)
Install-RemoteAccess -VpnType VpnS2S
# Add and configure S2S VPN interface
Add-VpnS2SInterface -Protocol IKEv2
-IPv4Subnet @(“172.16.0.0/16:100”) `
Set-VpnServerIPsecConfiguration -EncryptionType MaximumEncryption
Set-VpnS2Sinterface -Name ‘AZRGTW’ -InitiateConfigPayload $false -Force
# Set S2S VPN connection to be persistent by editing the router.pbk file (required admin priveleges)
Set-PrivateProfileString $env:windirSystem32rasrouter.pbk “22.214.171.124” “IdleDisconnectSeconds” “0”
Set-PrivateProfileString $env:windirSystem32rasrouter.pbk “126.96.36.199” “RedialOnLinkFailure” “1”
# Restart the RRAS service
# Dial-in to Azure gateway
Connect-VpnS2SInterface -Name AZRGTW
Once the modified/simplified script ran without issues, I was able to see the connection on both sides. In AWS on the Windows 2012 R2 edge device in the Routing and Remote Access Control Panel Applet.
And in Azure in the Azure portal, in the Virtual Network Gateway under Connections.
In the Amazon management console switch to the VPC view and select Route tables. Select the route table associated with your VPC and add a new route to the 172.16.0.0/16 (Windows Azure Network) and that routes traffic through the instance ID of the Server.
That’s it, our environments are connected.
I can ping the Windows machine in the Azure environment from the machines in AWS.
Here you go. Not that complicated
You can find the Azure VPN Gateway documentation here.