VPN Tunnels between AWS and GCP
This repository contains the infrastructure to create HA VPNs between an AWS VPC and a GCP project.
The infrastructure created was based on following this guide here
Note: This will require using Terraform 0.12
High-level configuration steps
Because HA VPN is dependent on BGP IP settings generated by AWS, you must configure Cloud VPN and AWS components in the following sequence:
- Create the HA VPN gateway and create a Cloud Router.
- Create one AWS virtual private gateway.
- Create two AWS site-to-site VPN connections and two customer gateways.
- Create four VPN tunnels on the HA VPN gateway.
- Configure BGP sessions on the Cloud Router using the BGP IP addresses from AWS
Permissions
In order to create the necessary infrastructure, we need special permissions.
On the Google Cloud side, we require a role with these permissions:
compute.addresses.create
compute.addresses.delete
compute.disks.create
compute.disks.delete
compute.externalVpnGateways.create
compute.externalVpnGateways.delete
compute.externalVpnGateways.use
compute.firewalls.create
compute.firewalls.delete
compute.networks.updatePolicy
compute.routers.create
compute.routers.delete
compute.routers.update
compute.routers.use
compute.subnetworks.use
compute.vpnGateways.create
compute.vpnGateways.delete
compute.vpnGateways.use
compute.vpnTunnels.create
compute.vpnTunnels.delete
On the AWS side, we require a role with these permissions:
ec2:AttachVpnGateway
ec2:CreateCustomerGateway
ec2:CreateTags
ec2:CreateVpnConnection
ec2:CreateVpnGateway
ec2:DeleteCustomerGateway
ec2:DeleteVpnConnection
ec2:DeleteVpnGateway
ec2:DetachVpnGateway
ec2:DescribeCustomerGateways
ec2:DescribeVpcs
ec2:DescribeVpnConnections
ec2:DescribeVpnGateways
How To Use
This module assumes that you have an existing AWS VPC and and exisiting GCP Network you would like to connect. If you do not have these, you will need to create these before using the module.
Assuming you have existing infrastructure, enter the AWS ID of your VPC and the region where your VPC resides in as well as the GCP Network Name and GCP Region where the Network is located, in to the correct input fields similar to the example below.
The remaining variables to define are the AWS_SIDE_ASN and the GCP_SIDE_ASN.
GCP_SIDE_ASN
This can be "Any private ASN (64512-65534, 4200000000-4294967294) that you are not already using in the peer network. The ASN is used for all BGP sessions on the same Cloud Router, and it cannot be changed later. All VPN tunnels that link to this router will have the same local ASN."
On the Google side, this needs to be set but as AWS Customer Gateway uses 65000
as the default, we will also have 65000
as the default
AWS_SIDE_ASN
Similar to tbe GCP_SIDE_ASN "You can choose any private ASN. Ranges for 16-bit private ASNs include 64512 to 65534. You can also provide 32-bit ASNs between 4200000000 and 4294967294. You cannot change the ASN later, changing the ASN wi;; required recreating all the infrastrcuture again"
Amazon will provide a default ASN for the virtual gateway if you don’t choose one. This default is 64512
, so we have made 64512
our defult also
module "aws-to-gcp-vpn" {
source = "[email protected]:uswitch/terraform-aws-to-gcp-vpn.git"
# AWS Variables
aws_vpc_id = << AWS_VPC_ID >>
aws_region = << AWS_VPC_REGION >>
aws_side_asn = << AMAZON_SIDE_ASN >>
gcp_side_asn = << GOOGLE_SIDE_ASN >>
# GCP Variables
gcp_network_name = << GCP_NETWORK_NAME >>
gcp_region = << GCP_REGION >>
}
This will spin up 2 VPNs and 4 tunnels between AWS and GCP.
To enable communication from the AWS side, you will need to create routes to the subnet where you would like to connect too.
For example:
resource "aws_route" "route_to_vpn_gateway" {
route_table_id = << ROUTE_TABLE_ID >>
destination_cidr_block = << GOOGLE_SUBNET_CIDR_RANGE >>
gateway_id = << VPN_GATEWAY_ID >>
}
ROUTE TABLE ID
is the ID of the Route Table associated to the subnet where your instance lives
GOOGLE_SUBNET_CIDR_RANGE
is the cidr range of your subnets in your GCP network.
VPN_GATEWAY_ID
is the ID of the VPN Gateway which can be accessed as an output from the module using something similar to module.aws-to-gcp-vpn.aws_vpn_gateway_id
We will also need to create Security Groups on the AWS side and Firewall Rules on the GCP side
AWS Security Group example:
resource "aws_security_group" "aws-to-gcp" {
name = "aws-to-gcp"
description = "Allow everything from GCP"
vpc_id = << VPC_ID >>
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = [ << GOOGLE_SUBNET_CIDR_RANGE >> ]
}
}
VPC_ID
is the ID of the VPC where the AWS subnets you want to communicate from, were created
GOOGLE_SUBNET_CIDR_RANGE
is the cidr range of your subnets in your GCP network.
GCP Firewall example:
resource "google_compute_firewall" "gcp-to-aws" {
name = "gcp-to-aws"
network = << GOOGLE_NETWORK_NAME >>
allow {
protocol = "tcp"
ports = ["0-65535"]
}
allow {
protocol = "udp"
ports = ["0-65535"]
}
source_ranges = [
<< AWS_SUBNET_CIDR_RANGE >>
]
}
GOOGLE_NETWORK_NAME
is the name of your Google Network
AWS_SUBNET_CIDR_RANGE
is the cidr range of your subnets in your AWS VPC.
Example
The example directory contains an example of how to use the module and the variables to be passed to the module.
In the example, instances and security groups are created in AWS and GCP allowing you to SSH on to the respective instances and ping the other instance to confirm connectivity.
To get the example to run, add an inputs.tfvars
file with the values for the variables in variables.tf
and run terraform plan --var-file=inputs.tfvars
and terraform apply --var-file=inputs.tfvars