preechadev / terraform-azure-aws-vpn-active-active-with-bgp

Terraform scripts which creates Active-Active with BGP full mesh S2S VPN connections between Azure and AWS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Introduction

These terrafrom scripts deploy full mesh Site to Site IPSEC VPN with BGP between Azure and AWS Cloud.
For detailed information refer to Azure Documentation.

In addition terraform scripts deploy also Virtual Machines (one on Azure Site and one on AWS site) which could be used for connectivity testing over VPN connections.

Resources

Note that this example creates resources in Azure and AWS cloud which can cost money. Run terraform destroy when you don't need these resources.

Azure Resources

Below table represents resources which terraform creates in Azure Cloud

Type Name Description TF file
Resource Group TestRG1 Azure Resource Group where all deployed Azure resources will be placed s2s-vpn-azure.tf
Virtual Network VNet1 Azure Virtual Network main.tf
Azure Subnet GatewaySubnet Subnet where Azure Network Gateway will be placed s2s-vpn-azure.tf
Azure Public IP VNet1GWpip Azure Public IP which will be associated to VPN Network Gateway Instance0 s2s-vpn-azure.tf
Azure Public IP VNet1GWpip2 Azure Public IP which will be associated to VPN Network Gateway Instance1 s2s-vpn-azure.tf
Azure Virtual Network Gateway VNet1GW Azure Virtual Network Gateway s2s-vpn-azure.tf
Azure Local Network Gateway AWSTunnel1ToInstance0 Azure Local Network Gateway - AWS Connection1 Tunnel1 s2s-vpn-azure.tf
Azure Local Network Gateway AWSTunnel2ToInstance0 Azure Local Network Gateway - AWS Connection1 Tunnel2 s2s-vpn-azure.tf
Azure Local Network Gateway AWSTunnel1ToInstance1 Azure Local Network Gateway - AWS Connection2 Tunnel1 s2s-vpn-azure.tf
Azure Local Network Gateway AWSTunnel2ToInstance1 Azure Local Network Gateway - AWS Connection2 Tunnel2 s2s-vpn-azure.tf
Connection AWSTunnel1ToInstance0 Azure VPN connection between Azure VPN Instance0 and AWS Connection1 Tunnel1 s2s-vpn-azure.tf
Connection AWSTunnel2ToInstance0 Azure VPN connection between Azure VPN Instance0 and AWS Connection1 Tunnel2 s2s-vpn-azure.tf
Connection AWSTunnel1ToInstance1 Azure VPN connection between Azure VPN Instance1 and AWS Connection2 Tunnel1 s2s-vpn-azure.tf
Connection AWSTunnel2ToInstance1 Azure VPN connection between Azure VPN Instance0 and AWS Connection2 Tunnel2 s2s-vpn-azure.tf
Azure Subnet vm-subnet Subnet where Azure Testing VM will be placed vm-test-azure.tf
Azure Security Group nsg-test-azure-vm Security group which will be assigned to Azure Test VM nic. SG allows SSH and ICMP trafic vm-test-azure.tf
Azure Public IP pip-test-azure-vm Azure Public IP which will be associated to Azure Test VM vm-test-azure.tf
Azure Network Interface nic-test-azure-vm Azure Network Interface will be associated to Azure Test VM vm-test-azure.tf
Azure Virtual Machine vpn-test-azure-vm Azure VM for VPN connectivity testing vm-test-azure.tf

AWS Resources

Below table represents resources which terraform creates in AWS Cloud.

Type Name Description TF file
AWS VPC VPC1 AWS VPC s2s-vpn-aws.tf
AWS Internet Gateway ig-test-aws-vm AWS Internet Gateway in VPC1 - Needed by AWS testing VM s2s-vpn-aws.tf
AWS Route Table vpn-route-table Route Table in VPC1 s2s-vpn-aws.tf
AWS VPC Subnet vpn-subnet Subnet in VPC1 for placing AWS testing VM s2s-vpn-aws.tf
AWS VPN Gateway vpn-gw AWS VPN Gateway s2s-vpn-aws.tf
AWS Customer Gateway ToAzureInstance0 AWS Customer Gateway representing Azure VPN Instance0 s2s-vpn-aws.tf
AWS Customer Gateway ToAzureInstance1 AWS Customer Gateway representing Azure VPN Instance1 s2s-vpn-aws.tf
AWS VPN Connection ToAzureInstance0 AWS VPN Connection to Azure VPN Instance0 s2s-vpn-aws.tf
AWS VPN Connection ToAzureInstance1 AWS VPN Connection to Azure VPN Instance1 s2s-vpn-aws.tf
AWS Network Interface nic-test-aws-vm Network Interface for AWS Test VM s2s-vpn-aws.tf
AWS Security Group vpn-test-sg Network Security Group for AWS Test VM s2s-vpn-aws.tf
AWS SSH Key Pair vpn-test-key-pair SSH Key Pair for AWS Test VM s2s-vpn-aws.tf
AWS EC2 Instance vpn-test-aws-vm AWS Test VM Instance s2s-vpn-aws.tf

Inputs

Below table represents terraform input variables

Name Description Type Default Required
azure_tenant ID of Azure Tenant. string none yes
azure_subscription ID of Azure Subscription. string none yes
azure_location ID of Azure Location string eastus yes
azure_vnet_prefix IP Prefix for Azure VNET1 list(string) 10.1.0.0/16 yes
azure_gateway_subnet_prefix Azure Subnet GatewaySubnet IP Prefix list(string) 10.1.0.0/24 yes
azure_vm_subnet_prefix Azure Test VM Subnet IP Prefix list(string) 10.1.100.0/24 yes
azure_vpn_gateway_sku Azure Network Gateway SKU string VpnGw1 yes
azure_vpn_gateway_asn Azure Network Gateway BGP ASN string 65515 yes
aws_region AWS Region where AWS resources will be deployed string eu-west-1 yes
azure_vnet_prefix AWS VPC1 prefix list(string) 10.2.0.0/16 yes
aws_vm_subnet_prefix AWS Test VM Subnet IP Prefix list(string) 10.2.100.0/24 yes
aws_vpn_gateway_asn AWS Gateway BGP ASN string 64512 yes
bgp_apipa_cidr_1 BGP APIPA CIDR 1 - AWS Tunnel 1 to Azure Instance 0 string 169.254.21.0/30 yes
bgp_apipa_cidr_2 BGP APIPA CIDR 2 - AWS Tunnel 2 to Azure Instance 0 string 169.254.22.0/30 yes
bgp_apipa_cidr_3 BGP APIPA CIDR 3 - AWS Tunnel 1 to Azure Instance 1 string 169.254.21.4/30 yes
bgp_apipa_cidr_4 BGP APIPA CIDR 4 - AWS Tunnel 2 to Azure Instance 1 string 169.254.22.4/30 yes
ipsec_policy IPSEC Protocols object(
{
dh_group = string
ike_encryption = string
ike_integrity = string
ipsec_encryption = string
ipsec_integrity = string
pfs_group = string
sa_datasize = string
sa_lifetime = string
}
)
dh_group = "ECP384"
ike_encryption = "GCMAES256"
ike_integrity = "SHA384"
ipsec_encryption = "GCMAES256"
ipsec_integrity = "GCMAES256"
pfs_group = "SHA384"
sa_datasize = "102400000"
sa_lifetime = "27000"
yes
ssh_public_key SSH Public Key for Testing VMs string none yes

Outputs

Below table represents terraform output variables.

Name Description
AzureInstance0_IP Azure Network Gateway Instance0 Public IP
AzureInstance1_IP Azure Network Gateway Instance1 Public IP
ToAzureInstance0_Tunnel1_IP AWS To AzureInstance0 Tunnel 1 Outside IP address
ToAzureInstance0_Tunnel2_IP AWS To AzureInstance0 Tunnel 2 Outside IP address
ToAzureInstance1_Tunnel1_IP AWS To AzureInstance1 Tunnel 1 Outside IP address
ToAzureInstance1_Tunnel2_IP AWS To AzureInstance1 Tunnel 2 Outside IP address
Azure_Test_VM_Public_IP Azure Test VM Public IP
Azure_Test_VM_Private_IP Azure Test VM Private IP
AWS_Test_VM_Public_IP AWS Test VM Public IP
AWS_Test_VM_Private_IP AWS Test VM Private IP
My_Public_IP Terraform deployment Public IP

VPN Site-to-Site

BGP APIPA Addresses

AWS will use the first IP address of /30 inside APIPA CIDR and Azure will use the second IP Address. Terraform cidrhost is used to calculate azure APIPA addresses from bgp_apipa_cidr variables.
Example:

  bgp_settings {
    asn = var.azure_vpn_gateway_asn

    peering_addresses {
      ip_configuration_name = "vnetGatewayConfig-1"
      apipa_addresses       = [cidrhost(var.bgp_apipa_cidr_1, 2), cidrhost(var.bgp_apipa_cidr_2, 2)]
    }

    peering_addresses {
      ip_configuration_name = "vnetGatewayConfig-2"
      apipa_addresses       = [cidrhost(var.bgp_apipa_cidr_3, 2), cidrhost(var.bgp_apipa_cidr_4, 2)]
    }
  }

Pre-shared keys

Terraform generates VPN connections pre-shared keys on the fly by using terraform random_password resources.

resource "random_password" "AWSTunnel1ToInstance0-PSK" {
  length  = 16
  special = false
}

resource "random_password" "AWSTunnel2ToInstance0-PSK" {
  length  = 16
  special = false
}

resource "random_password" "AWSTunnel1ToInstance1-PSK" {
  length  = 16
  special = false
}

resource "random_password" "AWSTunnel2ToInstance1-PSK" {
  length  = 16
  special = false
}

Testing Virtual Machines

Terraform scripts deploy Virtual Machines (one on Azure Site and one on AWS site) which could be used for connectivity testing over VPN connections.

SSH Public Key

Each of testing Virtual Machine requires to use ssh keys for SSH connection. Before deploying terrform scripts include your public ssh key into terraform variable "ssh_public_key".

The following usernames are used for VM SSH login.

VM instance username
Azure Testing VM ubuntu
AWS Testing VM ec2-user

Security Groups

Communication to testing VM is restricted by Security Groups.
SSH connection to Virtual Machines is allowed only from IP address where tf scrips are executed. Public deployment IP address is automatically obtained by terraform http data-source.

data "http" "source_ip" {
  url = "https://ifconfig.me"
}

For VPN testing purposes IMCP traffic is allowed between Azure VNET and AWS VPC CIDR.

Security Group Rules for Azure Testing VM

resource "azurerm_network_security_rule" "nsg-test-azure-vm-rule-1" {
  name                        = "ssh"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "*"
  destination_port_range      = "22"
  source_address_prefix       = "${data.http.source_ip.body}/32"
  destination_address_prefix  = "*"
  description                 = "Test-SSH."
  resource_group_name         = azurerm_resource_group.vpn-rg.name
  network_security_group_name = azurerm_network_security_group.nsg-test-azure-vm.name
}

resource "azurerm_network_security_rule" "nsg-test-azure-vm-rule-2" {
  name                        = "icmp"
  priority                    = 101
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Icmp"
  source_port_range           = "*"
  destination_port_range      = "*"
  source_address_prefix       = var.aws_vnet_prefix
  destination_address_prefix  = "*"
  description                 = "Test-ICMP"
  resource_group_name         = azurerm_resource_group.vpn-rg.name
  network_security_group_name = azurerm_network_security_group.nsg-test-azure-vm.name
}

Security Group Rules for AWS Testing VM

resource "aws_security_group" "vpn-test-sg" {
  name        = "vpn-test-sg"
  description = "Security Group For testing vpn connectivity"
  vpc_id      = aws_vpc.aws-vpc.id

  ingress {
    description = "SSH into VPC"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["${data.http.source_ip.body}/32"]
  }

  ingress {
    description = "ICMP into VPC"
    from_port   = -1
    to_port     = -1
    protocol    = "icmp"
    cidr_blocks = var.azure_vnet_prefix
  }

  egress {
    description = "Outbound Allowed"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "vpn-test-sg"
  }
}

Usage

To run this example you need to execute:

$ terraform init
$ terraform plan
$ terraform apply

Requirements

Name Version
terraform >= 0.14.9
aws >= 3.63
azurerm >= 3.0.2

Providers

Name Version
aws >= 3.63
azurerm >= 3.0.2

Modules

No modules.

Limitation

Terraform azurerm does not yet support enabling Custom BGP Addresses for Azure connections. Please refer to hashicorp/terraform-provider-azurerm#15854

Without changing Custom BGP Addresses for Azure connections BGP routes are properly advertised through AWSTunnel1ToInstance0 and AWSTunnel1ToInstance1 but tunnels AWSTunnel2ToInstance0 and AWSTunnel2ToInstance1 advertise wrong APIPA address.

To have all tunnels properly advertise routes there need to be changed Custom BGP Addresses for AWSTunnel2ToInstance0 and AWSTunnel2ToInstance1.

  • AWSTunnel2ToInstance0 -> Primary Custom BGP Address change to 169.254.22.2
  • AWSTunnel2ToInstance1 -> Secondary Custom BGP Address change to 169.254.22.6

About

Terraform scripts which creates Active-Active with BGP full mesh S2S VPN connections between Azure and AWS

License:Apache License 2.0


Languages

Language:HCL 100.0%