diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf
index c39878d1..1086f19c 100644
--- a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf
+++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf
@@ -32,8 +32,8 @@ module "apigee_vpn" {
mode = "CUSTOM"
}
}
- peer_gateway = {
- gcp = module.onprem_vpn.self_link
+ peer_gateways = {
+ default = { gcp = module.onprem_vpn.self_link }
}
tunnels = {
0 = {
@@ -82,8 +82,8 @@ module "onprem_vpn" {
mode = "CUSTOM"
}
}
- peer_gateway = {
- gcp = module.apigee_vpn.self_link
+ peer_gateways = {
+ default = { gcp = module.apigee_vpn.self_link }
}
tunnels = {
0 = {
diff --git a/blueprints/networking/hub-and-spoke-vpn/vpn-dev-r1.tf b/blueprints/networking/hub-and-spoke-vpn/vpn-dev-r1.tf
index 4d1236bb..49ced394 100644
--- a/blueprints/networking/hub-and-spoke-vpn/vpn-dev-r1.tf
+++ b/blueprints/networking/hub-and-spoke-vpn/vpn-dev-r1.tf
@@ -27,7 +27,9 @@ module "landing-to-dev-vpn-r1" {
name = "${var.prefix}-lnd-vpn-r1"
asn = 64514
}
- peer_gateway = { gcp = module.dev-to-landing-vpn-r1.self_link }
+ peer_gateways = {
+ default = { gcp = module.dev-to-landing-vpn-r1.self_link }
+ }
tunnels = {
0 = {
bgp_peer = {
@@ -63,7 +65,9 @@ module "dev-to-landing-vpn-r1" {
mode = "CUSTOM"
}
}
- peer_gateway = { gcp = module.landing-to-dev-vpn-r1.self_link }
+ peer_gateways = {
+ default = { gcp = module.landing-to-dev-vpn-r1.self_link }
+ }
tunnels = {
0 = {
bgp_peer = {
diff --git a/blueprints/networking/hub-and-spoke-vpn/vpn-prod-r1.tf b/blueprints/networking/hub-and-spoke-vpn/vpn-prod-r1.tf
index 8e633686..8c025d9e 100644
--- a/blueprints/networking/hub-and-spoke-vpn/vpn-prod-r1.tf
+++ b/blueprints/networking/hub-and-spoke-vpn/vpn-prod-r1.tf
@@ -28,7 +28,9 @@ module "landing-to-prod-vpn-r1" {
ip_ranges = coalesce(var.vpn_configs.land-r1.custom_ranges, {})
}
}
- peer_gateway = { gcp = module.prod-to-landing-vpn-r1.self_link }
+ peer_gateways = {
+ default = { gcp = module.prod-to-landing-vpn-r1.self_link }
+ }
tunnels = {
0 = {
bgp_peer = {
@@ -64,7 +66,9 @@ module "prod-to-landing-vpn-r1" {
ip_ranges = coalesce(var.vpn_configs.prod-r1.custom_ranges, {})
}
}
- peer_gateway = { gcp = module.landing-to-prod-vpn-r1.self_link }
+ peer_gateways = {
+ default = { gcp = module.landing-to-prod-vpn-r1.self_link }
+ }
tunnels = {
0 = {
bgp_peer = {
diff --git a/blueprints/networking/private-cloud-function-from-onprem/main.tf b/blueprints/networking/private-cloud-function-from-onprem/main.tf
index 1848e953..49bab252 100644
--- a/blueprints/networking/private-cloud-function-from-onprem/main.tf
+++ b/blueprints/networking/private-cloud-function-from-onprem/main.tf
@@ -86,7 +86,9 @@ module "vpn-onprem" {
ip_ranges = {}
}
}
- peer_gateway = { gcp = module.vpn-hub.self_link }
+ peer_gateways = {
+ default = { gcp = module.vpn-hub.self_link }
+ }
tunnels = {
tunnel-0 = {
bgp_peer = {
@@ -122,7 +124,9 @@ module "vpn-hub" {
}
}
}
- peer_gateway = { gcp = module.vpn-onprem.self_link }
+ peer_gateways = {
+ default = { gcp = module.vpn-onprem.self_link }
+ }
tunnels = {
tunnel-0 = {
diff --git a/blueprints/serverless/cloud-run-corporate/main.tf b/blueprints/serverless/cloud-run-corporate/main.tf
index 88f853d7..5eb98029 100644
--- a/blueprints/serverless/cloud-run-corporate/main.tf
+++ b/blueprints/serverless/cloud-run-corporate/main.tf
@@ -540,13 +540,15 @@ module "vpc_sc" {
# VPN between main project and "onprem" environment
module "vpn_main" {
- source = "../../../modules/net-vpn-ha"
- count = length(module.project_onprem)
- project_id = module.project_main.project_id
- region = var.region
- network = module.vpc_main.self_link
- name = "vpn-main-to-onprem"
- peer_gateway = { gcp = module.vpn_onprem[0].self_link }
+ source = "../../../modules/net-vpn-ha"
+ count = length(module.project_onprem)
+ project_id = module.project_main.project_id
+ region = var.region
+ network = module.vpc_main.self_link
+ name = "vpn-main-to-onprem"
+ peer_gateways = {
+ default = { gcp = module.vpn_onprem[0].self_link }
+ }
router_config = {
asn = 65001
custom_advertise = {
@@ -577,13 +579,15 @@ module "vpn_main" {
}
module "vpn_onprem" {
- source = "../../../modules/net-vpn-ha"
- count = length(module.project_onprem)
- project_id = module.project_onprem[0].project_id
- region = var.region
- network = module.vpc_onprem[0].self_link
- name = "vpn-onprem-to-main"
- peer_gateway = { gcp = module.vpn_main[0].self_link }
+ source = "../../../modules/net-vpn-ha"
+ count = length(module.project_onprem)
+ project_id = module.project_onprem[0].project_id
+ region = var.region
+ network = module.vpc_onprem[0].self_link
+ name = "vpn-onprem-to-main"
+ peer_gateways = {
+ default = { gcp = module.vpn_main[0].self_link }
+ }
router_config = { asn = 65002 }
tunnels = {
tunnel-0 = {
diff --git a/fast/stages/2-networking-a-peering/vpn-onprem.tf b/fast/stages/2-networking-a-peering/vpn-onprem.tf
index a04a0097..2e9f3c24 100644
--- a/fast/stages/2-networking-a-peering/vpn-onprem.tf
+++ b/fast/stages/2-networking-a-peering/vpn-onprem.tf
@@ -48,8 +48,10 @@ module "landing-to-onprem-primary-vpn" {
name = "landing-onprem-vpn-${local.region_shortnames[var.regions.primary]}"
asn = var.router_onprem_configs.landing-primary.asn
}
- peer_gateway = {
- external = var.vpn_onprem_configs.landing-primary.peer_external_gateway
+ peer_gateways = {
+ default = {
+ external = var.vpn_onprem_configs.landing-primary.peer_external_gateway
+ }
}
tunnels = {
for t in var.vpn_onprem_configs.landing-primary.tunnels :
diff --git a/fast/stages/2-networking-b-vpn/vpn-onprem.tf b/fast/stages/2-networking-b-vpn/vpn-onprem.tf
index a04a0097..2e9f3c24 100644
--- a/fast/stages/2-networking-b-vpn/vpn-onprem.tf
+++ b/fast/stages/2-networking-b-vpn/vpn-onprem.tf
@@ -48,8 +48,10 @@ module "landing-to-onprem-primary-vpn" {
name = "landing-onprem-vpn-${local.region_shortnames[var.regions.primary]}"
asn = var.router_onprem_configs.landing-primary.asn
}
- peer_gateway = {
- external = var.vpn_onprem_configs.landing-primary.peer_external_gateway
+ peer_gateways = {
+ default = {
+ external = var.vpn_onprem_configs.landing-primary.peer_external_gateway
+ }
}
tunnels = {
for t in var.vpn_onprem_configs.landing-primary.tunnels :
diff --git a/fast/stages/2-networking-b-vpn/vpn-spoke-dev.tf b/fast/stages/2-networking-b-vpn/vpn-spoke-dev.tf
index 09cc31e0..97adc642 100644
--- a/fast/stages/2-networking-b-vpn/vpn-spoke-dev.tf
+++ b/fast/stages/2-networking-b-vpn/vpn-spoke-dev.tf
@@ -50,7 +50,9 @@ module "landing-to-dev-primary-vpn" {
name = "landing-vpn-${local.region_shortnames[var.regions.primary]}"
asn = var.router_spoke_configs.landing-primary.asn
}
- peer_gateway = { gcp = module.dev-to-landing-primary-vpn.self_link }
+ peer_gateways = {
+ default = { gcp = module.dev-to-landing-primary-vpn.self_link }
+ }
tunnels = {
0 = {
bgp_peer = {
@@ -95,7 +97,9 @@ module "dev-to-landing-primary-vpn" {
name = "dev-spoke-vpn-${local.region_shortnames[var.regions.primary]}"
asn = var.router_spoke_configs.spoke-dev-primary.asn
}
- peer_gateway = { gcp = module.landing-to-dev-primary-vpn.self_link }
+ peer_gateways = {
+ default = { gcp = module.landing-to-dev-primary-vpn.self_link }
+ }
tunnels = {
0 = {
bgp_peer = {
diff --git a/fast/stages/2-networking-b-vpn/vpn-spoke-prod-primary.tf b/fast/stages/2-networking-b-vpn/vpn-spoke-prod-primary.tf
index 071b1d05..9d36c16e 100644
--- a/fast/stages/2-networking-b-vpn/vpn-spoke-prod-primary.tf
+++ b/fast/stages/2-networking-b-vpn/vpn-spoke-prod-primary.tf
@@ -33,7 +33,9 @@ module "landing-to-prod-primary-vpn" {
name = "landing-vpn-${local.region_shortnames[var.regions.primary]}"
asn = var.router_spoke_configs.landing-primary.asn
}
- peer_gateway = { gcp = module.prod-to-landing-primary-vpn.self_link }
+ peer_gateways = {
+ default = { gcp = module.prod-to-landing-primary-vpn.self_link }
+ }
tunnels = {
0 = {
bgp_peer = {
@@ -75,7 +77,9 @@ module "prod-to-landing-primary-vpn" {
name = "prod-spoke-vpn-${local.region_shortnames[var.regions.primary]}"
asn = var.router_spoke_configs.spoke-prod-primary.asn
}
- peer_gateway = { gcp = module.landing-to-prod-primary-vpn.self_link }
+ peer_gateways = {
+ default = { gcp = module.landing-to-prod-primary-vpn.self_link }
+ }
tunnels = {
0 = {
bgp_peer = {
diff --git a/fast/stages/2-networking-b-vpn/vpn-spoke-prod-secondary.tf b/fast/stages/2-networking-b-vpn/vpn-spoke-prod-secondary.tf
index a7c0e0fe..a3ee9e9f 100644
--- a/fast/stages/2-networking-b-vpn/vpn-spoke-prod-secondary.tf
+++ b/fast/stages/2-networking-b-vpn/vpn-spoke-prod-secondary.tf
@@ -33,7 +33,9 @@ module "landing-to-prod-secondary-vpn" {
name = "landing-vpn-${local.region_shortnames[var.regions.secondary]}"
asn = var.router_spoke_configs.landing-secondary.asn
}
- peer_gateway = { gcp = module.prod-to-landing-secondary-vpn.self_link }
+ peer_gateways = {
+ default = { gcp = module.prod-to-landing-secondary-vpn.self_link }
+ }
tunnels = {
0 = {
bgp_peer = {
@@ -75,7 +77,9 @@ module "prod-to-landing-secondary-vpn" {
name = "prod-spoke-vpn-${local.region_shortnames[var.regions.secondary]}"
asn = var.router_spoke_configs.spoke-prod-secondary.asn
}
- peer_gateway = { gcp = module.landing-to-prod-secondary-vpn.self_link }
+ peer_gateways = {
+ default = { gcp = module.landing-to-prod-secondary-vpn.self_link }
+ }
tunnels = {
0 = {
bgp_peer = {
diff --git a/fast/stages/2-networking-c-nva/vpn-onprem.tf b/fast/stages/2-networking-c-nva/vpn-onprem.tf
index 57f2024a..31adbe71 100644
--- a/fast/stages/2-networking-c-nva/vpn-onprem.tf
+++ b/fast/stages/2-networking-c-nva/vpn-onprem.tf
@@ -51,8 +51,10 @@ module "landing-to-onprem-primary-vpn" {
name = "landing-onprem-vpn-${local.region_shortnames[var.regions.primary]}"
asn = var.router_configs.landing-trusted-primary.asn
}
- peer_gateway = {
- external = var.vpn_onprem_configs.landing-trusted-primary.peer_external_gateway
+ peer_gateways = {
+ default = {
+ external = var.vpn_onprem_configs.landing-trusted-primary.peer_external_gateway
+ }
}
tunnels = {
for t in var.vpn_onprem_configs.landing-trusted-primary.tunnels :
@@ -85,8 +87,10 @@ module "landing-to-onprem-secondary-vpn" {
name = "landing-onprem-vpn-${local.region_shortnames[var.regions.secondary]}"
asn = var.router_configs.landing-trusted-secondary.asn
}
- peer_gateway = {
- external = var.vpn_onprem_configs.landing-trusted-secondary.peer_external_gateway
+ peer_gateways = {
+ default = {
+ external = var.vpn_onprem_configs.landing-trusted-secondary.peer_external_gateway
+ }
}
tunnels = {
for t in var.vpn_onprem_configs.landing-trusted-secondary.tunnels :
diff --git a/fast/stages/2-networking-d-separate-envs/vpn-onprem-dev.tf b/fast/stages/2-networking-d-separate-envs/vpn-onprem-dev.tf
index e95cd14f..c5269c4d 100644
--- a/fast/stages/2-networking-d-separate-envs/vpn-onprem-dev.tf
+++ b/fast/stages/2-networking-d-separate-envs/vpn-onprem-dev.tf
@@ -48,8 +48,10 @@ module "dev-to-onprem-primary-vpn" {
name = "dev-onprem-vpn-${local.region_shortnames[var.regions.primary]}"
asn = var.router_onprem_configs.dev-primary.asn
}
- peer_gateway = {
- external = var.vpn_onprem_configs.dev-primary.peer_external_gateway
+ peer_gateways = {
+ default = {
+ external = var.vpn_onprem_configs.dev-primary.peer_external_gateway
+ }
}
tunnels = {
for t in var.vpn_onprem_configs.dev-primary.tunnels :
diff --git a/fast/stages/2-networking-d-separate-envs/vpn-onprem-prod.tf b/fast/stages/2-networking-d-separate-envs/vpn-onprem-prod.tf
index 0793e274..760ba4e5 100644
--- a/fast/stages/2-networking-d-separate-envs/vpn-onprem-prod.tf
+++ b/fast/stages/2-networking-d-separate-envs/vpn-onprem-prod.tf
@@ -32,8 +32,10 @@ module "prod-to-onprem-primary-vpn" {
name = "prod-onprem-vpn-${local.region_shortnames[var.regions.primary]}"
asn = var.router_onprem_configs.prod-primary.asn
}
- peer_gateway = {
- external = var.vpn_onprem_configs.prod-primary.peer_external_gateway
+ peer_gateways = {
+ default = {
+ external = var.vpn_onprem_configs.prod-primary.peer_external_gateway
+ }
}
tunnels = {
for t in var.vpn_onprem_configs.prod-primary.tunnels :
diff --git a/modules/net-vpn-ha/README.md b/modules/net-vpn-ha/README.md
index 0b7b5290..8bbac84d 100644
--- a/modules/net-vpn-ha/README.md
+++ b/modules/net-vpn-ha/README.md
@@ -1,17 +1,21 @@
# Cloud HA VPN Module
+
This module makes it easy to deploy either GCP-to-GCP or GCP-to-On-prem [Cloud HA VPN](https://cloud.google.com/vpn/docs/concepts/overview#ha-vpn).
## Examples
### GCP to GCP
+
```hcl
module "vpn-1" {
- source = "./fabric/modules/net-vpn-ha"
- project_id = var.project_id
- region = "europe-west4"
- network = var.vpc1.self_link
- name = "net1-to-net-2"
- peer_gateway = { gcp = module.vpn-2.self_link }
+ source = "./fabric/modules/net-vpn-ha"
+ project_id = var.project_id
+ region = "europe-west4"
+ network = var.vpc1.self_link
+ name = "net1-to-net-2"
+ peer_gateways = {
+ default = { gcp = module.vpn-2.self_link }
+ }
router_config = {
asn = 64514
custom_advertise = {
@@ -48,7 +52,9 @@ module "vpn-2" {
network = var.vpc2.self_link
name = "net2-to-net1"
router_config = { asn = 64513 }
- peer_gateway = { gcp = module.vpn-1.self_link }
+ peer_gateways = {
+ default = { gcp = module.vpn-1.self_link }
+ }
tunnels = {
remote-0 = {
bgp_peer = {
@@ -84,10 +90,12 @@ module "vpn_ha" {
region = var.region
network = var.vpc.self_link
name = "mynet-to-onprem"
- peer_gateway = {
- external = {
- redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
- interfaces = ["8.8.8.8"] # on-prem router ip address
+ peer_gateways = {
+ default = {
+ external = {
+ redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
+ interfaces = ["8.8.8.8"] # on-prem router ip address
+ }
}
}
router_config = { asn = 64514 }
@@ -124,13 +132,13 @@ module "vpn_ha" {
|---|---|:---:|:---:|:---:|
| [name](variables.tf#L17) | VPN Gateway name (if an existing VPN Gateway is not used), and prefix used for dependent resources. | string
| ✓ | |
| [network](variables.tf#L22) | VPC used for the gateway and routes. | string
| ✓ | |
-| [peer_gateway](variables.tf#L27) | Configuration of the (external or GCP) peer gateway. | object({…})
| ✓ | |
-| [project_id](variables.tf#L43) | Project where resources will be created. | string
| ✓ | |
-| [region](variables.tf#L48) | Region used for resources. | string
| ✓ | |
-| [router_config](variables.tf#L53) | Cloud Router configuration for the VPN. If you want to reuse an existing router, set create to false and use name to specify the desired router. | object({…})
| ✓ | |
-| [tunnels](variables.tf#L68) | VPN tunnel configurations. | map(object({…}))
| | {}
|
-| [vpn_gateway](variables.tf#L95) | HA VPN Gateway Self Link for using an existing HA VPN Gateway. Ignored if `vpn_gateway_create` is set to `true`. | string
| | null
|
-| [vpn_gateway_create](variables.tf#L101) | Create HA VPN Gateway. | bool
| | true
|
+| [project_id](variables.tf#L46) | Project where resources will be created. | string
| ✓ | |
+| [region](variables.tf#L51) | Region used for resources. | string
| ✓ | |
+| [router_config](variables.tf#L56) | Cloud Router configuration for the VPN. If you want to reuse an existing router, set create to false and use name to specify the desired router. | object({…})
| ✓ | |
+| [peer_gateways](variables.tf#L27) | Configuration of the (external or GCP) peer gateway. | map(object({…}))
| | {}
|
+| [tunnels](variables.tf#L71) | VPN tunnel configurations. | map(object({…}))
| | {}
|
+| [vpn_gateway](variables.tf#L99) | HA VPN Gateway Self Link for using an existing HA VPN Gateway. Ignored if `vpn_gateway_create` is set to `true`. | string
| | null
|
+| [vpn_gateway_create](variables.tf#L105) | Create HA VPN Gateway. | bool
| | true
|
## Outputs
diff --git a/modules/net-vpn-ha/main.tf b/modules/net-vpn-ha/main.tf
index 9d53ee08..1925cdfc 100644
--- a/modules/net-vpn-ha/main.tf
+++ b/modules/net-vpn-ha/main.tf
@@ -16,6 +16,12 @@
*/
locals {
+ peer_gateways_external = {
+ for k, v in var.peer_gateways : k => v.external if v.external != null
+ }
+ peer_gateways_gcp = {
+ for k, v in var.peer_gateways : k => v.gcp if v.gcp != null
+ }
router = (
var.router_config.create
? try(google_compute_router.router[0].name, null)
@@ -38,13 +44,13 @@ resource "google_compute_ha_vpn_gateway" "ha_gateway" {
}
resource "google_compute_external_vpn_gateway" "external_gateway" {
- count = var.peer_gateway.external != null ? 1 : 0
- name = "external-${var.name}"
+ for_each = local.peer_gateways_external
+ name = "${var.name}-${each.key}"
project = var.project_id
- redundancy_type = var.peer_gateway.external.redundancy_type
+ redundancy_type = each.value.redundancy_type
description = "Terraform managed external VPN gateway"
dynamic "interface" {
- for_each = var.peer_gateway.external.interfaces
+ for_each = each.value.interfaces
content {
id = interface.key
ip_address = interface.value
@@ -124,18 +130,23 @@ resource "google_compute_router_interface" "router_interface" {
}
resource "google_compute_vpn_tunnel" "tunnels" {
- for_each = var.tunnels
- project = var.project_id
- region = var.region
- name = "${var.name}-${each.key}"
- router = local.router
- peer_external_gateway = one(google_compute_external_vpn_gateway.external_gateway[*].self_link)
+ for_each = var.tunnels
+ project = var.project_id
+ region = var.region
+ name = "${var.name}-${each.key}"
+ router = local.router
+ peer_external_gateway = try(
+ google_compute_external_vpn_gateway.external_gateway[each.value.peer_gateway],
+ null
+ )
peer_external_gateway_interface = each.value.peer_external_gateway_interface
- peer_gcp_gateway = var.peer_gateway.gcp
- vpn_gateway_interface = each.value.vpn_gateway_interface
- ike_version = each.value.ike_version
- shared_secret = coalesce(each.value.shared_secret, local.secret)
- vpn_gateway = local.vpn_gateway
+ peer_gcp_gateway = lookup(
+ local.peer_gateways_gcp, each.value.peer_gateway, null
+ )
+ vpn_gateway_interface = each.value.vpn_gateway_interface
+ ike_version = each.value.ike_version
+ shared_secret = coalesce(each.value.shared_secret, local.secret)
+ vpn_gateway = local.vpn_gateway
}
resource "random_id" "secret" {
diff --git a/modules/net-vpn-ha/variables.tf b/modules/net-vpn-ha/variables.tf
index a423eab1..b12c4cdc 100644
--- a/modules/net-vpn-ha/variables.tf
+++ b/modules/net-vpn-ha/variables.tf
@@ -24,18 +24,21 @@ variable "network" {
type = string
}
-variable "peer_gateway" {
+variable "peer_gateways" {
description = "Configuration of the (external or GCP) peer gateway."
- type = object({
+ type = map(object({
external = optional(object({
redundancy_type = string
interfaces = list(string)
}))
gcp = optional(string)
- })
+ }))
nullable = false
+ default = {}
validation {
- condition = (var.peer_gateway.external != null) != (var.peer_gateway.gcp != null)
+ condition = alltrue([
+ for k, v in var.peer_gateways : (v.external != null) != (v.gcp != null)
+ ])
error_message = "Peer gateway configuration must define exactly one between `external` and `gcp`."
}
}
@@ -84,6 +87,7 @@ variable "tunnels" {
bgp_session_range = string
ike_version = optional(number, 2)
peer_external_gateway_interface = optional(number)
+ peer_gateway = optional(string, "default")
router = optional(string)
shared_secret = optional(string)
vpn_gateway_interface = number