Allow multiple peer gateways in vpn ha module (#1184)

* allow multiple peer gateways in vpn ha module

* align blueprints

* fast
This commit is contained in:
Ludovico Magnocavallo 2023-02-27 11:18:59 +01:00 committed by GitHub
parent 067ca37e50
commit 6320c53baf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 142 additions and 79 deletions

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 :

View File

@ -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 :

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 = {

View File

@ -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 :

View File

@ -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 :

View File

@ -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 :

View File

@ -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. | <code>string</code> | ✓ | |
| [network](variables.tf#L22) | VPC used for the gateway and routes. | <code>string</code> | ✓ | |
| [peer_gateway](variables.tf#L27) | Configuration of the (external or GCP) peer gateway. | <code title="object&#40;&#123;&#10; external &#61; optional&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; gcp &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [project_id](variables.tf#L43) | Project where resources will be created. | <code>string</code> | ✓ | |
| [region](variables.tf#L48) | Region used for resources. | <code>string</code> | ✓ | |
| [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. | <code title="object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | |
| [tunnels](variables.tf#L68) | VPN tunnel configurations. | <code title="map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [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`. | <code>string</code> | | <code>null</code> |
| [vpn_gateway_create](variables.tf#L101) | Create HA VPN Gateway. | <code>bool</code> | | <code>true</code> |
| [project_id](variables.tf#L46) | Project where resources will be created. | <code>string</code> | ✓ | |
| [region](variables.tf#L51) | Region used for resources. | <code>string</code> | ✓ | |
| [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. | <code title="object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [peer_gateways](variables.tf#L27) | Configuration of the (external or GCP) peer gateway. | <code title="map&#40;object&#40;&#123;&#10; external &#61; optional&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; gcp &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [tunnels](variables.tf#L71) | VPN tunnel configurations. | <code title="map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [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`. | <code>string</code> | | <code>null</code> |
| [vpn_gateway_create](variables.tf#L105) | Create HA VPN Gateway. | <code>bool</code> | | <code>true</code> |
## Outputs

View File

@ -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" {

View File

@ -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