net-vpn-ha (#3420)

This commit is contained in:
Ludovico Magnocavallo
2025-10-16 09:08:17 +02:00
committed by GitHub
parent ccecb0dd24
commit 45d4674ae8
6 changed files with 279 additions and 28 deletions

View File

@@ -223,15 +223,16 @@ You can optionally avoid to specify MD5 keys and the module will automatically g
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [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> | ✓ | |
| [project_id](variables.tf#L48) | Project where resources will be created. | <code>string</code> | ✓ | |
| [region](variables.tf#L53) | Region used for resources. | <code>string</code> | ✓ | |
| [router_config](variables.tf#L58) | 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; asn &#61; optional&#40;number&#41;&#10; create &#61; optional&#40;bool, true&#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; keepalive &#61; optional&#40;number&#41;&#10; name &#61; optional&#40;string&#41;&#10; override_name &#61; optional&#40;string&#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; description &#61; optional&#40;string, &#34;Terraform managed external VPN gateway&#34;&#41;&#10; name &#61; optional&#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#L74) | 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; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; md5_authentication_key &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; key &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; ipv6 &#61; optional&#40;object&#40;&#123;&#10; nexthop_address &#61; optional&#40;string&#41;&#10; peer_nexthop_address &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; name &#61; optional&#40;string&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; name &#61; optional&#40;string&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_router_interface_name &#61; optional&#40;string&#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#L111) | 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#L117) | Create HA VPN Gateway. Set to null to avoid creation. | <code title="object&#40;&#123;&#10; description &#61; optional&#40;string, &#34;Terraform managed external VPN gateway&#34;&#41;&#10; ipv6 &#61; optional&#40;bool, false&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [name](variables.tf#L31) | VPN Gateway name (if an existing VPN Gateway is not used), and prefix used for dependent resources. | <code>string</code> | ✓ | |
| [network](variables.tf#L36) | VPC used for the gateway and routes. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L62) | Project where resources will be created. | <code>string</code> | ✓ | |
| [region](variables.tf#L67) | Region used for resources. | <code>string</code> | ✓ | |
| [router_config](variables.tf#L72) | 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; asn &#61; optional&#40;number&#41;&#10; create &#61; optional&#40;bool, true&#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; keepalive &#61; optional&#40;number&#41;&#10; name &#61; optional&#40;string&#41;&#10; override_name &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [context](variables.tf#L17) | Context-specific interpolations. | <code title="object&#40;&#123;&#10; addresses &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; locations &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; networks &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; project_ids &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; routers &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; vpn_gateways &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [peer_gateways](variables.tf#L41) | 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; description &#61; optional&#40;string, &#34;Terraform managed external VPN gateway&#34;&#41;&#10; name &#61; optional&#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#L88) | 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; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; md5_authentication_key &#61; optional&#40;object&#40;&#123;&#10; name &#61; string&#10; key &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; ipv6 &#61; optional&#40;object&#40;&#123;&#10; nexthop_address &#61; optional&#40;string&#41;&#10; peer_nexthop_address &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; name &#61; optional&#40;string&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; name &#61; optional&#40;string&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_router_interface_name &#61; optional&#40;string&#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#L125) | 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#L131) | Create HA VPN Gateway. Set to null to avoid creation. | <code title="object&#40;&#123;&#10; description &#61; optional&#40;string, &#34;Terraform managed external VPN gateway&#34;&#41;&#10; ipv6 &#61; optional&#40;bool, false&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
## Outputs

View File

@@ -16,25 +16,39 @@
*/
locals {
ctx = {
for k, v in var.context : k => {
for kk, vv in v : "${local.ctx_p}${k}:${kk}" => vv
}
}
ctx_p = "$"
md5_keys = {
for k, v in random_id.md5_keys
: k => v.b64_url
}
network = lookup(local.ctx.networks, var.network, var.network)
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
for k, v in var.peer_gateways :
k => lookup(local.ctx.vpn_gateways, v.gcp, v.gcp) if v.gcp != null
}
project_id = lookup(
local.ctx.project_ids, var.project_id, var.project_id
)
region = lookup(
local.ctx.locations, var.region, var.region
)
router = (
var.router_config.create
? try(google_compute_router.router[0].name, null)
: var.router_config.name
: lookup(local.ctx.routers, var.router_config.name, var.router_config.name)
)
vpn_gateway = (
var.vpn_gateway_create != null
? try(google_compute_ha_vpn_gateway.ha_gateway[0].self_link, null)
: var.vpn_gateway
: lookup(local.ctx.vpn_gateways, var.vpn_gateway, var.vpn_gateway)
)
secret = random_id.secret.b64_url
}
@@ -43,23 +57,23 @@ resource "google_compute_ha_vpn_gateway" "ha_gateway" {
count = var.vpn_gateway_create != null ? 1 : 0
name = var.name
description = var.vpn_gateway_create.description
project = var.project_id
region = var.region
network = var.network
project = local.project_id
region = local.region
network = local.network
stack_type = var.vpn_gateway_create.ipv6 ? "IPV4_IPV6" : "IPV4_ONLY"
}
resource "google_compute_external_vpn_gateway" "external_gateway" {
for_each = local.peer_gateways_external
name = each.value.name != null ? each.value.name : "${var.name}-${each.key}"
project = var.project_id
project = local.project_id
redundancy_type = each.value.redundancy_type
description = each.value.description
dynamic "interface" {
for_each = each.value.interfaces
content {
id = interface.key
ip_address = interface.value
ip_address = lookup(local.ctx.addresses, interface.value, interface.value)
}
}
}
@@ -67,9 +81,9 @@ resource "google_compute_external_vpn_gateway" "external_gateway" {
resource "google_compute_router" "router" {
count = var.router_config.create ? 1 : 0
name = coalesce(var.router_config.name, "vpn-${var.name}")
project = var.project_id
region = var.region
network = var.network
project = local.project_id
region = local.region
network = local.network
bgp {
advertise_mode = (
var.router_config.custom_advertise != null
@@ -96,8 +110,8 @@ resource "google_compute_router" "router" {
resource "google_compute_router_peer" "bgp_peer" {
for_each = var.tunnels
region = var.region
project = var.project_id
region = local.region
project = local.project_id
name = each.value.bgp_peer.name != null ? each.value.bgp_peer.name : "${var.name}-${each.key}"
router = coalesce(each.value.router, local.router)
peer_ip_address = each.value.bgp_peer.address
@@ -132,10 +146,14 @@ resource "google_compute_router_peer" "bgp_peer" {
resource "google_compute_router_interface" "router_interface" {
for_each = var.tunnels
project = var.project_id
region = var.region
name = each.value.peer_router_interface_name != null ? each.value.peer_router_interface_name : "${var.name}-${each.key}"
router = local.router
project = local.project_id
region = local.region
name = (
each.value.peer_router_interface_name != null
? each.value.peer_router_interface_name :
"${var.name}-${each.key}"
)
router = local.router
# FIXME: can bgp_session_range be null?
ip_range = each.value.bgp_session_range == "" ? null : each.value.bgp_session_range
vpn_tunnel = google_compute_vpn_tunnel.tunnels[each.key].name
@@ -143,8 +161,8 @@ resource "google_compute_router_interface" "router_interface" {
resource "google_compute_vpn_tunnel" "tunnels" {
for_each = var.tunnels
project = var.project_id
region = var.region
project = local.project_id
region = local.region
name = each.value.name != null ? each.value.name : "${var.name}-${each.key}"
router = local.router
peer_external_gateway = try(

View File

@@ -14,6 +14,20 @@
* limitations under the License.
*/
variable "context" {
description = "Context-specific interpolations."
type = object({
addresses = optional(map(string), {})
locations = optional(map(string), {})
networks = optional(map(string), {})
project_ids = optional(map(string), {})
routers = optional(map(string), {})
vpn_gateways = optional(map(string), {})
})
default = {}
nullable = false
}
variable "name" {
description = "VPN Gateway name (if an existing VPN Gateway is not used), and prefix used for dependent resources."
type = string