Often times companies with sizeable deployments opt to run their infrastructure on multiple platforms or environments. This can be their own on-premises datacenter, or multiple cloud platforms. Azure Virtual Gateways allow for any service deployment on-premises as well deployments running on other clouds such as AWS to interact, providing redundancy and failover necessary for very high reliability.
This template will create all the Azure infrastructure necessary to connect to an existing AWS VPC, without the need of powershell. This guide uses StrongSwan for the VPN IPSec software and is largely based a few articles:
- Connecting to a Windows Azure Virtual Network via a Linux Based Software VPN Device
- Connecting Clouds – Creating a site-to-site Network with Amazon Web Services and Windows Azure
- Create a virtual network with a site-to-site VPN connection using Azure Resource Manager and PowerShell
Although unlike the guides above, this guide specifically details connecting to an Amazon AWS VPC using Azure Resource Manager.
If you already have a VPC setup, go ahead an skip this section.
Using the AWS console, create a new VPC, you can give a big address space such as 10.0.0.0/16
:
Create a new subnet and associate it with the given vpc. Any subnet size will do as long as its within a subset of the ip address space defined in the previous step. I'm going with 10.0.0.0/24
.
Then launch an EC2 Ubuntu instance with connected to the VPC and subnet created in the step above:
Disable source/destination checking on the instance:
Now, in your VPC, allocate a new Elastic IP (public ip) address and associate it with the instance:
If you haven't already, its a good idea to change or at least add the hostname of your EC2 instance to it's /etc/hosts
file (pointing to 127.0.0.1
) as StrongSwan's ipsec command seems to look for your current instance's hostname on the network:
vim /etc/hostname
vim /etc/hosts
sudo service hostname restart
Deploying the Azure VNet and connection is made easy with the included resource manager template. This template includes a VirutalNetworkGateway, a LocalNetworkGateway and a VirtualNetworkGatewayConnection, as well as an instance to connect to an existing AWS VPC.
First, fill in the required parameters defined by [azuredeploy-parameters.json](./azuredeploy- parameters.json). This includes vpcGatewayIpAddress
, vpcAddressPrefix
, sharedKey
and adminPassword
. There's also lots of other parameters you can change which you can find within the template file. The most important parameters are vpcGatewayIpAddress
which is the public IP of the EC2 instance created above and vpcAddressPrefix
which is the CIDR block of the VPC subnet.
To deploy the parameters using the azure cli create a new resource group then deploy the template to it.
azure group create aws2azure westus
azure group deployment create aws2azure --template-file azuredeploy.json --parameters-file azuredeploy-parameters.json
As of writing this a resource manger deployment with a virtual network gateway allocation may take up to 30 minutes to provision. Hopefully that gets fixed soon!
Afterwards you can verify within the Resource Explorer blade on portal.azure.com that the resource group you deployed to contains a VirtualNetworkGatewayConnection to the AWS VPC.
We need some details from the Azure deployment in order to complete configuring the VPC on the AWS side. First, we need to add a route to the VPC routing table and associate it with our subnet.
Add a route to the route table associated with the VPC, with the Azure Subnet CIDR as the destination, and the EC2 instance as the target:
Be sure to associate the routing table with your VPC and your Amazon VPC Subnet.
Next, go to your security group associated with the ec2 instance and add 2 inbound custom UDP rules for ports 500 and 4500. The source for both should be a fixed single address CIDR block pointing your Azure VirtualNetworkGateway public IP formatted as: [Azure VNet Public IP]/32
.
Finally, we need to setup the EC2 instance as an StrongSwan VPN server for the VPC. We can do this by ssh
'ing into the instance and setting up Strongswan:
sudo apt-get update
sugo apt-get install strongswan
Now, modify the strongswan configuration file /etc/ipsec.conf
with a new connection called azure
:
conn azure
authby=secret
type=tunnel
leftsendcert=never
left=10.0.0.28
leftsubnet=10.0.0.0/24
#leftnexthop=%defaultroute
right=[AZURE GATEWAY PUBLIC IP]
rightsubnet=10.3.0.0/24
keyexchange=ikev2
ikelifetime=10800s
keylife=57m
keyingtries=1
rekeymargin=3m
#pfs=no
compress=no
auto=start
Here are the keys you should change for your specific deployment:
left
- The local ip address of the strongswan serverleftsubnet
- The local subnet of the VPCright
- The public IP address of the Azure VNet Gatewayrightsubnet
- The local subnet of the Azure VNet (not to be confused with the gateway subnet)
Now we need to provide StrongSwan with the shared secret. To do this modify the file /etc/ipsec.secrets
and add the line, replacing with your own values (do not include the []
brackets):
[STRONGSWAN LOCAL IP] [AZURE VNET GATEWAY PUBLIC IP] : PSK "[YOUR SHARED KEY]"
This should match the shared key used in the azure template parameters from the previous section.
For the strong swan instance to forward traffic between Azure VNet and AWS VPC, we'll have to enable forwarding. On the EC2 instance, uncomment or add the following line to the file, /etc/sysctl.conf
:
net.ipv4.ip_forward=1
Now, just restart the ipsec service and you should see a connection:
ipsec restart
ipsec status
Security Associations (1 up, 0 connecting):
azure[1]: ESTABLISHED 3 seconds ago, 10.0.0.28[10.0.0.28]...AZURE PUBLIC IP[AZURE PUBLIC IP]
azure{1}: INSTALLED, TUNNEL, ESP in UDP SPIs: c3e607f3_i 280cade0_o
azure{1}: 10.0.0.0/24 === 10.3.0.0/24
We've already created an Ubuntu instance in Azure by deploying the template. Create another Ubuntu instance on AWS, associated with the same VPC, subnet and security group.
In order to configure Ubuntu to respond to ping requests, run this command on both the AWS and Azure Ubuntu instances:
iptables -A INPUT -p icmp -j ACCEPT
From the AWS instance, attempt to ping the Azure instance:
ping [Azure Instance Local IP]
64 bytes from 10.0.0.232: icmp_seq=892 ttl=62 time=26.1 ms
64 bytes from 10.0.0.232: icmp_seq=893 ttl=62 time=26.2 ms
64 bytes from 10.0.0.232: icmp_seq=894 ttl=62 time=25.8 ms
...
64 bytes from 10.0.0.232: icmp_seq=929 ttl=62 time=25.4 ms
You should see the same thing as well when you ping the the Azure instance:
ping [AWS Instance Local IP]
64 bytes from 10.0.0.232: icmp_seq=892 ttl=62 time=26.1 ms
64 bytes from 10.0.0.232: icmp_seq=893 ttl=62 time=26.2 ms
64 bytes from 10.0.0.232: icmp_seq=894 ttl=62 time=25.8 ms
...
64 bytes from 10.0.0.232: icmp_seq=896 ttl=62 time=26.1 ms
You now have two subnets that are connected, one on AWS the other on Azure. Enjoy.