Add context support to vlan-attachments (#3787)

This commit is contained in:
Simone Ruffilli
2026-03-13 08:12:04 +01:00
committed by GitHub
parent 7c3b08b1d1
commit 5bb0862638
6 changed files with 194 additions and 30 deletions

View File

@@ -646,19 +646,20 @@ module "example-va-b" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [description](variables.tf#L36) | VLAN attachment description. | <code>string</code> | ✓ | |
| [name](variables.tf#L53) | The common resources name, used after resource type prefix and suffix. | <code>string</code> | ✓ | |
| [network](variables.tf#L58) | The VPC name to which resources are associated to. | <code>string</code> | ✓ | |
| [peer_asn](variables.tf#L75) | The on-premises underlay router ASN. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L80) | The project id where resources are created. | <code>string</code> | ✓ | |
| [region](variables.tf#L85) | The region where resources are created. | <code>string</code> | ✓ | |
| [router_config](variables.tf#L90) | 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; optional&#40;number, 65001&#41;&#10; bfd &#61; optional&#40;object&#40;&#123;&#10; min_receive_interval &#61; optional&#40;number&#41;&#10; min_transmit_interval &#61; optional&#40;number&#41;&#10; multiplier &#61; optional&#40;number&#41;&#10; session_initialization_mode &#61; optional&#40;string, &#34;ACTIVE&#34;&#41;&#10; &#125;&#41;&#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; keepalive &#61; optional&#40;number&#41;&#10; name &#61; optional&#40;string, &#34;router&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [description](variables.tf#L52) | VLAN attachment description. | <code>string</code> | ✓ | |
| [name](variables.tf#L69) | The common resources name, used after resource type prefix and suffix. | <code>string</code> | ✓ | |
| [network](variables.tf#L74) | The VPC name to which resources are associated to. | <code>string</code> | ✓ | |
| [peer_asn](variables.tf#L91) | The on-premises underlay router ASN. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L96) | The project id where resources are created. | <code>string</code> | ✓ | |
| [region](variables.tf#L101) | The region where resources are created. | <code>string</code> | ✓ | |
| [router_config](variables.tf#L106) | 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; optional&#40;number, 65001&#41;&#10; bfd &#61; optional&#40;object&#40;&#123;&#10; min_receive_interval &#61; optional&#40;number&#41;&#10; min_transmit_interval &#61; optional&#40;number&#41;&#10; multiplier &#61; optional&#40;number&#41;&#10; session_initialization_mode &#61; optional&#40;string, &#34;ACTIVE&#34;&#41;&#10; &#125;&#41;&#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; keepalive &#61; optional&#40;number&#41;&#10; name &#61; optional&#40;string, &#34;router&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [admin_enabled](variables.tf#L17) | Whether the VLAN attachment is enabled. | <code>bool</code> | | <code>true</code> |
| [dedicated_interconnect_config](variables.tf#L23) | Dedicated interconnect configuration. | <code title="object&#40;&#123;&#10; bandwidth &#61; optional&#40;string, &#34;BPS_10G&#34;&#41;&#10; bgp_range &#61; optional&#40;string&#41;&#10; bgp_priority &#61; optional&#40;number&#41;&#10; interconnect &#61; string&#10; vlan_tag &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [ipsec_gateway_ip_ranges](variables.tf#L41) | IPSec Gateway IP Ranges. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [mtu](variables.tf#L47) | The MTU associated to the VLAN attachment (1440 / 1500). | <code>number</code> | | <code>1500</code> |
| [partner_interconnect_config](variables.tf#L63) | Partner interconnect configuration. | <code title="object&#40;&#123;&#10; edge_availability_domain &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [vpn_gateways_ip_range](variables.tf#L115) | The IP range (cidr notation) to be used for the GCP VPN gateways. If null IPSec over Interconnect is not enabled. | <code>string</code> | | <code>null</code> |
| [context](variables.tf#L23) | Context-specific interpolations. | <code title="object&#40;&#123;&#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;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [dedicated_interconnect_config](variables.tf#L35) | Dedicated interconnect configuration. | <code title="object&#40;&#123;&#10; bandwidth &#61; optional&#40;string, &#34;BPS_10G&#34;&#41;&#10; bgp_range &#61; optional&#40;string&#41;&#10; bgp_priority &#61; optional&#40;number&#41;&#10; interconnect &#61; string&#10; vlan_tag &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [ipsec_gateway_ip_ranges](variables.tf#L57) | IPSec Gateway IP Ranges. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [mtu](variables.tf#L63) | The MTU associated to the VLAN attachment (1440 / 1500). | <code>number</code> | | <code>1500</code> |
| [partner_interconnect_config](variables.tf#L79) | Partner interconnect configuration. | <code title="object&#40;&#123;&#10; edge_availability_domain &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [vpn_gateways_ip_range](variables.tf#L131) | The IP range (cidr notation) to be used for the GCP VPN gateways. If null IPSec over Interconnect is not enabled. | <code>string</code> | | <code>null</code> |
## Outputs

View File

@@ -15,20 +15,30 @@
*/
locals {
ctx_p = "$"
ctx = {
for k, v in var.context : k => {
for kk, vv in v : "${local.ctx_p}${k}:${kk}" => vv
}
}
ipsec_enabled = var.vpn_gateways_ip_range == null ? false : true
network = lookup(local.ctx.networks, var.network, var.network)
project_id = lookup(local.ctx.project_ids, var.project_id, var.project_id)
region = lookup(local.ctx.locations, var.region, var.region)
router_name = lookup(local.ctx.routers, try(var.router_config.name, ""), try(var.router_config.name, ""))
router = (
var.router_config.create
? local.ipsec_enabled ? try(google_compute_router.encrypted[0].name, null) : try(google_compute_router.unencrypted[0].name, null)
: var.router_config.name
: local.router_name
)
secret = random_id.secret.b64_url
}
resource "google_compute_address" "default" {
count = local.ipsec_enabled ? 1 : 0
project = var.project_id
network = var.network
region = var.region
project = local.project_id
network = local.network
region = local.region
name = "pool-${var.name}"
address_type = "INTERNAL"
purpose = "IPSEC_INTERCONNECT"
@@ -37,15 +47,15 @@ resource "google_compute_address" "default" {
}
resource "google_compute_interconnect_attachment" "default" {
project = var.project_id
region = var.region
project = local.project_id
region = local.region
router = local.router
name = var.name
description = var.description
interconnect = try(var.dedicated_interconnect_config.interconnect, null)
bandwidth = try(var.dedicated_interconnect_config.bandwidth, null)
mtu = local.ipsec_enabled ? null : var.mtu
candidate_subnets = var.dedicated_interconnect_config != null ? [var.dedicated_interconnect_config.bgp_range] : null
candidate_subnets = try(var.dedicated_interconnect_config.bgp_range, null) != null ? [var.dedicated_interconnect_config.bgp_range] : null
vlan_tag8021q = try(var.dedicated_interconnect_config.vlan_tag, null)
admin_enabled = var.admin_enabled
encryption = local.ipsec_enabled ? "IPSEC" : null
@@ -57,9 +67,9 @@ resource "google_compute_interconnect_attachment" "default" {
resource "google_compute_router" "encrypted" {
count = var.router_config.create && local.ipsec_enabled ? 1 : 0
name = "${var.name}-underlay"
network = var.network
project = var.project_id
region = var.region
network = local.network
project = local.project_id
region = local.region
encrypted_interconnect_router = true
bgp {
asn = var.router_config.asn
@@ -76,10 +86,10 @@ resource "google_compute_router" "encrypted" {
resource "google_compute_router" "unencrypted" {
count = var.router_config.create && !local.ipsec_enabled ? 1 : 0
name = coalesce(var.router_config.name, "underlay-${var.name}")
project = var.project_id
region = var.region
network = var.network
name = coalesce(local.router_name, "underlay-${var.name}")
project = local.project_id
region = local.region
network = local.network
bgp {
advertise_mode = (
var.router_config.custom_advertise != null
@@ -106,8 +116,8 @@ resource "google_compute_router" "unencrypted" {
resource "google_compute_router_interface" "default" {
count = var.dedicated_interconnect_config != null ? 1 : 0
project = var.project_id
region = var.region
project = local.project_id
region = local.region
name = "${var.name}-intf"
router = local.router
ip_range = google_compute_interconnect_attachment.default.cloud_router_ip_address
@@ -117,9 +127,9 @@ resource "google_compute_router_interface" "default" {
resource "google_compute_router_peer" "default" {
count = var.dedicated_interconnect_config != null ? 1 : 0
name = "${var.name}-peer"
project = var.project_id
project = local.project_id
router = local.router
region = var.region
region = local.region
peer_ip_address = split("/", google_compute_interconnect_attachment.default.customer_router_ip_address)[0]
peer_asn = var.peer_asn
interface = google_compute_router_interface.default[0].name

View File

@@ -20,6 +20,18 @@ variable "admin_enabled" {
default = true
}
variable "context" {
description = "Context-specific interpolations."
type = object({
locations = optional(map(string), {})
networks = optional(map(string), {})
project_ids = optional(map(string), {})
routers = optional(map(string), {})
})
default = {}
nullable = false
}
variable "dedicated_interconnect_config" {
description = "Dedicated interconnect configuration."
type = object({
@@ -30,6 +42,10 @@ variable "dedicated_interconnect_config" {
interconnect = string
vlan_tag = string
})
validation {
condition = var.dedicated_interconnect_config == null ? true : contains(["BPS_50M", "BPS_100M", "BPS_200M", "BPS_300M", "BPS_400M", "BPS_500M", "BPS_1G", "BPS_2G", "BPS_5G", "BPS_10G", "BPS_20G", "BPS_50G", "BPS_100G", "BPS_400G"], var.dedicated_interconnect_config.bandwidth)
error_message = "The bandwidth must be one of BPS_50M, BPS_100M, BPS_200M, BPS_300M, BPS_400M, BPS_500M, BPS_1G, BPS_2G, BPS_5G, BPS_10G, BPS_20G, BPS_50G, BPS_100G, BPS_400G."
}
default = null
}