Establish a Site to Site (S2S) VPN Natively between your AWS VPCs

Erich Borchert
5 min readJul 29, 2021

--

Nick Matthews from AWS got me thinking when he posted about AWS allowing you to initiate IKE for their Site-to-Site VPN offerings.

What if you wanted to create a VPN between Virtual Private Gateways or Transit Gateways in AWS? Azure supports it so I wanted to see if something similar could be done in AWS but I couldn’t find any documentation so I decided to experiment and document my findings. The solution created from my findings is a bit of a hack so not recommended for real world. Something more robust might use certs which then could automatically discover the endpoints??

This solution helps with two issues.

  1. Creates a IPSEC VPN between VPCs, either intra or inter-region, without having to configure any appliances in your AWS Account
  2. Encrypts VPC to VPC traffic (Inter-Region is already encrypted)

When you build a VPN Connection there are two tunnels created for redundancy. For this solution, I am just going to configure one of the tunnels. So let’s illustrate what my topology looks like when I am using a Virtual Private Gateway (VGW) and Transit Gateway (TGW).

Option 1 Site to Site VPN between Virtual Private Gateways

Site to Site VPN between VGWs
Virtual Private Gateway IPEC VPN Between VPCs

Option 2 Site to Site VPN between Transit Gateways

Site to Site VPN between TGWs
Transit Gateways with VPN between them used to encrypt VPC to VPC traffic

For this post I will show you how to complete option #1. But I have posted the CloudFormation for Option #2 as well.

TLDR: CloudFormation Templates for the TGW and VGW can be found here. Run one template for each site, 10.0.0.0/24 = Site1 and 192.168.0.0/24 = Site2, and follow the instructions in the Readme

Whether you want to standup the VPN via TGW or VGW here are the critical points to remember

  1. Change the VPN Connection Startup Action to Start on one side ( whichever side you want) . This config option is found in the Modify VPN Tunnel Options setting
  2. The first VPN, Site1 in my case, must be setup with a placeholder IP address (1.1.1.1, for example).
  3. Grab the Outside Tunnel IP addresses when you provision the VPN. This becomes your CGW for other side. I.E., Outside Tunnel for Site1 becomes CGW for Site2’s VPN connection and Outside Tunnel for Site2 becomes CGW for Site1 VPN.
  4. Make sure your VPNs have their static routes configured

Let’s walk through each of these in detail.

Grab the Outside Tunnel IP addresses:

Obtain the Public IPs for the VPNs and use them as Customer Gateways in the CloudFormation Template

For this setup to work you must document the Tunnel Outside IP Address on both sides. You find the Outside Tunnel IP address by going to the VPN connection, selecting Tunnel Details and Documenting the Outside IP Address

Alternatively you can run this CLI command

aws ec2 describe-vpn-connections — vpn-connection-ids vpn-<vpn-id> | jq ‘.VpnConnections[0].Options.TunnelOptions[0].OutsideIpAddress’

The finding from above means when I create the VPN connection from Site2 to Site1 I input a CGW IP of 52.10.56.157. This IP will be different in your case.

CloudFormation illustration of CGW for Site2
CloudFormation Output showing Site1, Tunnel1 Outside IP Address as an input to Site2’s VPN

Change the VPN Connection Startup Action to Start :

When AWS Introduced the capability to initiate IKE session it made this solution possible. Pick one VPN session to allow IKE to initiate and run this command

aws ec2 modify-vpn-tunnel-options --vpn-connection-id vpn-<vpn connectoin id> --vpn-tunnel-outside-ip-address <tunnel outside IP that is being modified. see previous step> --tunnel-option StartupAction=start
Verifying Startup Action Set from the Console

The first VPN, Site1 in my case, must be setup with a dummy IP address:

For this solution you execute the vpn-vgw-site-to-site.yml template two times.

First Execution (Site1 to Site2 VPN)

  • Specify a placeholder IP for Site2 CGW

Second Execution ( Site2 to Site1 VPN)

  • Specify Site1’s Real Outside IP Address ( obtained from first execution )

Finally you execute manual steps:

  • document the outside tunnel1 IP address of Site2 VPN to Site1
  • you will create a new CGW for Site2 ( This is for the Site1 to Site2 VPN)
  • associate this CGW with the Site1 VPN. Recall, we used a placeholder IP for Site1s VPN. Now we need to update it with the real IP of Site2.

Make sure your VPNs have their static routes configured

Don’t forget the static VPN routes or connectivity won’t be established. So for Site1, I need to route to Site2 which is 192.168.0.0/24 so I will add a static route. Similarly, for Site2 I add a route for Site1’s CIDR: 10.0.0.0/24

Static Route on Site1 for Site2’s CIDR

You have completed the critical pieces for an AWS VPC to VPC IPSEC VPN. The main takeaways are

  1. The first tunnel you provision will have a placeholder IP for the CGW
  2. Document the Tunnel Outside IP addresses and use them as Customer Gateways
  3. Manually create the Customer Gateway representing Site2 Tunnel1 Outside Address and associate it with the Site1 to Site2 VPN.
  4. Make sure your SecurityGroups are allowing traffic between the CIDRs and your route tables are appropriately updated. Note, the CF template will update the Route Table for you just make sure you provide the correct parameters.

--

--