main.tf (189 lines of code) (raw):
# Copyright 2020 Spotify AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
locals {
ha_vpn_interfaces_ips = [
for x in google_compute_ha_vpn_gateway.gateway.vpn_interfaces :
lookup(x, "ip_address")
]
suffix = var.suffix != "null" ? var.suffix : random_string.suffix.result
external_vpn_gateway_interfaces = {
"0" = {
tunnel_address = aws_vpn_connection.vpn-alpha.tunnel1_address
vgw_inside_address = aws_vpn_connection.vpn-alpha.tunnel1_vgw_inside_address
asn = aws_vpn_connection.vpn-alpha.tunnel1_bgp_asn
cgw_inside_address = "${aws_vpn_connection.vpn-alpha.tunnel1_cgw_inside_address}/30"
shared_secret = aws_vpn_connection.vpn-alpha.tunnel1_preshared_key
vpn_gateway_interface = 0
},
"1" = {
tunnel_address = aws_vpn_connection.vpn-alpha.tunnel2_address
vgw_inside_address = aws_vpn_connection.vpn-alpha.tunnel2_vgw_inside_address
asn = aws_vpn_connection.vpn-alpha.tunnel2_bgp_asn
cgw_inside_address = "${aws_vpn_connection.vpn-alpha.tunnel2_cgw_inside_address}/30"
shared_secret = aws_vpn_connection.vpn-alpha.tunnel2_preshared_key
vpn_gateway_interface = 0
},
"2" = {
tunnel_address = aws_vpn_connection.vpn-beta.tunnel1_address
vgw_inside_address = aws_vpn_connection.vpn-beta.tunnel1_vgw_inside_address
asn = aws_vpn_connection.vpn-beta.tunnel1_bgp_asn
cgw_inside_address = "${aws_vpn_connection.vpn-beta.tunnel1_cgw_inside_address}/30"
shared_secret = aws_vpn_connection.vpn-beta.tunnel1_preshared_key
vpn_gateway_interface = 1
},
"3" = {
tunnel_address = aws_vpn_connection.vpn-beta.tunnel2_address
vgw_inside_address = aws_vpn_connection.vpn-beta.tunnel2_vgw_inside_address
asn = aws_vpn_connection.vpn-beta.tunnel2_bgp_asn
cgw_inside_address = "${aws_vpn_connection.vpn-beta.tunnel2_cgw_inside_address}/30"
shared_secret = aws_vpn_connection.vpn-beta.tunnel2_preshared_key
vpn_gateway_interface = 1
},
}
}
data "aws_region" "current" {}
data "google_project" "project" {}
resource "random_string" "suffix" {
length = 10
special = false
upper = false
}
resource "google_compute_ha_vpn_gateway" "gateway" {
provider = google-beta
name = "ha-vpn-gw-to-aws-${data.aws_region.current.name}-${local.suffix}"
project = data.google_project.project.project_id
network = var.google_network
}
# Can't loop the cgw because TF errors with : Terraform value depends on resource attributes that cannot be determined
# until apply, so Terraform cannot predict how many instances will be created.
# We know for each GW there will always be 2 interfaces so maybe a map of alpha/beta if we want a loop. For now
# I'm leaving as separate resources.
resource "aws_customer_gateway" "cgw-alpha" {
bgp_asn = var.google_side_asn
ip_address = google_compute_ha_vpn_gateway.gateway.vpn_interfaces[0].ip_address
type = "ipsec.1"
tags = {
Name = "aws-to-google-vpn-gateway-alpha-${local.suffix}"
}
}
resource "aws_customer_gateway" "cgw-beta" {
bgp_asn = var.google_side_asn
ip_address = google_compute_ha_vpn_gateway.gateway.vpn_interfaces[1].ip_address
type = "ipsec.1"
tags = {
Name = "aws-to-google-vpn-gateway-beta-${local.suffix}"
}
}
// TODO Track this Issue and implement when ready https://github.com/terraform-providers/terraform-provider-aws/issues/11584
resource "aws_vpn_connection" "vpn-alpha" {
customer_gateway_id = aws_customer_gateway.cgw-alpha.id
transit_gateway_id = var.transit_gateway_id
type = aws_customer_gateway.cgw-alpha.type
tunnel1_phase1_encryption_algorithms = var.aws_vpn_configs.encryption_algorithms
tunnel2_phase1_encryption_algorithms = var.aws_vpn_configs.encryption_algorithms
tunnel1_phase1_integrity_algorithms = var.aws_vpn_configs.integrity_algorithms
tunnel2_phase1_integrity_algorithms = var.aws_vpn_configs.integrity_algorithms
tunnel1_phase1_dh_group_numbers = var.aws_vpn_configs.dh_group_numbers
tunnel2_phase1_dh_group_numbers = var.aws_vpn_configs.dh_group_numbers
tunnel1_phase2_encryption_algorithms = var.aws_vpn_configs.encryption_algorithms
tunnel2_phase2_encryption_algorithms = var.aws_vpn_configs.encryption_algorithms
tunnel1_phase2_integrity_algorithms = var.aws_vpn_configs.integrity_algorithms
tunnel2_phase2_integrity_algorithms = var.aws_vpn_configs.integrity_algorithms
tunnel1_phase2_dh_group_numbers = var.aws_vpn_configs.dh_group_numbers
tunnel2_phase2_dh_group_numbers = var.aws_vpn_configs.dh_group_numbers
tags = {
"Name" = "vpn-to-google-alpha-${local.suffix}"
}
}
resource "aws_vpn_connection" "vpn-beta" {
customer_gateway_id = aws_customer_gateway.cgw-beta.id
transit_gateway_id = var.transit_gateway_id
type = aws_customer_gateway.cgw-beta.type
tunnel1_phase1_encryption_algorithms = var.aws_vpn_configs.encryption_algorithms
tunnel2_phase1_encryption_algorithms = var.aws_vpn_configs.encryption_algorithms
tunnel1_phase1_integrity_algorithms = var.aws_vpn_configs.integrity_algorithms
tunnel2_phase1_integrity_algorithms = var.aws_vpn_configs.integrity_algorithms
tunnel1_phase1_dh_group_numbers = var.aws_vpn_configs.dh_group_numbers
tunnel2_phase1_dh_group_numbers = var.aws_vpn_configs.dh_group_numbers
tunnel1_phase2_encryption_algorithms = var.aws_vpn_configs.encryption_algorithms
tunnel2_phase2_encryption_algorithms = var.aws_vpn_configs.encryption_algorithms
tunnel1_phase2_integrity_algorithms = var.aws_vpn_configs.integrity_algorithms
tunnel2_phase2_integrity_algorithms = var.aws_vpn_configs.integrity_algorithms
tunnel1_phase2_dh_group_numbers = var.aws_vpn_configs.dh_group_numbers
tunnel2_phase2_dh_group_numbers = var.aws_vpn_configs.dh_group_numbers
tags = {
"Name" = "vpn-to-google-beta-${local.suffix}"
}
}
resource "google_compute_router" "router" {
provider = google-beta
name = "cr-to-aws-tgw-ha-vpn-${data.aws_region.current.name}-${local.suffix}"
network = var.google_network
description = "Google to AWS via Transit GW connection for AWS region ${data.aws_region.current.name}"
bgp {
asn = var.google_side_asn
advertise_mode = (
var.router_advertise_config == null
? null
: var.router_advertise_config.mode
)
advertised_groups = (
var.router_advertise_config == null ? null : (
var.router_advertise_config.mode != "CUSTOM"
? null
: var.router_advertise_config.groups
)
)
dynamic "advertised_ip_ranges" {
for_each = (
var.router_advertise_config == null ? {} : (
var.router_advertise_config.mode != "CUSTOM"
? null
: var.router_advertise_config.ip_ranges
)
)
iterator = range
content {
range = range.key
description = range.value
}
}
}
}
resource "google_compute_external_vpn_gateway" "external_gateway" {
provider = google-beta
name = "aws-${var.transit_gateway_id}-${data.aws_region.current.name}-${local.suffix}"
redundancy_type = "FOUR_IPS_REDUNDANCY"
description = "AWS Transit GW: ${var.transit_gateway_id} in AWS region ${data.aws_region.current.name}"
dynamic "interface" {
for_each = local.external_vpn_gateway_interfaces
content {
id = interface.key
ip_address = interface.value["tunnel_address"]
}
}
}
resource "google_compute_vpn_tunnel" "tunnels" {
provider = google-beta
for_each = local.external_vpn_gateway_interfaces
name = "tunnel${each.key}-${google_compute_router.router.name}"
description = "Tunnel to AWS - HA VPN interface ${each.key} to AWS interface ${each.value.tunnel_address}"
router = google_compute_router.router.self_link
ike_version = 2
shared_secret = each.value.shared_secret
vpn_gateway = google_compute_ha_vpn_gateway.gateway.self_link
vpn_gateway_interface = each.value.vpn_gateway_interface
peer_external_gateway = google_compute_external_vpn_gateway.external_gateway.self_link
peer_external_gateway_interface = each.key
}
resource "google_compute_router_interface" "interfaces" {
provider = google-beta
for_each = local.external_vpn_gateway_interfaces
name = "interface${each.key}-${google_compute_router.router.name}"
router = google_compute_router.router.name
ip_range = each.value.cgw_inside_address
vpn_tunnel = google_compute_vpn_tunnel.tunnels[each.key].name
}
resource "google_compute_router_peer" "router_peers" {
provider = google-beta
for_each = local.external_vpn_gateway_interfaces
name = "peer${each.key}-${google_compute_router.router.name}"
router = google_compute_router.router.name
peer_ip_address = each.value.vgw_inside_address
peer_asn = each.value.asn
interface = google_compute_router_interface.interfaces[each.key].name
}