Add context support to vlan-attachments (#3787)
This commit is contained in:
@@ -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({ create = optional(bool, true) asn = optional(number, 65001) bfd = optional(object({ min_receive_interval = optional(number) min_transmit_interval = optional(number) multiplier = optional(number) session_initialization_mode = optional(string, "ACTIVE") })) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) md5_authentication_key = optional(object({ name = string key = optional(string) })) keepalive = optional(number) name = optional(string, "router") })">object({…})</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({ create = optional(bool, true) asn = optional(number, 65001) bfd = optional(object({ min_receive_interval = optional(number) min_transmit_interval = optional(number) multiplier = optional(number) session_initialization_mode = optional(string, "ACTIVE") })) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) md5_authentication_key = optional(object({ name = string key = optional(string) })) keepalive = optional(number) name = optional(string, "router") })">object({…})</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({ bandwidth = optional(string, "BPS_10G") bgp_range = optional(string) bgp_priority = optional(number) interconnect = string vlan_tag = string })">object({…})</code> | | <code>null</code> |
|
||||
| [ipsec_gateway_ip_ranges](variables.tf#L41) | IPSec Gateway IP Ranges. | <code>map(string)</code> | | <code>{}</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({ edge_availability_domain = string })">object({…})</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({ locations = optional(map(string), {}) networks = optional(map(string), {}) project_ids = optional(map(string), {}) routers = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> |
|
||||
| [dedicated_interconnect_config](variables.tf#L35) | Dedicated interconnect configuration. | <code title="object({ bandwidth = optional(string, "BPS_10G") bgp_range = optional(string) bgp_priority = optional(number) interconnect = string vlan_tag = string })">object({…})</code> | | <code>null</code> |
|
||||
| [ipsec_gateway_ip_ranges](variables.tf#L57) | IPSec Gateway IP Ranges. | <code>map(string)</code> | | <code>{}</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({ edge_availability_domain = string })">object({…})</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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
35
tests/modules/net-vlan-attachment/context.tfvars
Normal file
35
tests/modules/net-vlan-attachment/context.tfvars
Normal file
@@ -0,0 +1,35 @@
|
||||
context = {
|
||||
locations = {
|
||||
my_region = "europe-west1"
|
||||
}
|
||||
networks = {
|
||||
my_network = "projects/my-project/global/networks/my-network"
|
||||
}
|
||||
project_ids = {
|
||||
my_project = "my-project"
|
||||
}
|
||||
routers = {
|
||||
my_router = "my-router"
|
||||
}
|
||||
}
|
||||
|
||||
dedicated_interconnect_config = {
|
||||
bandwidth = "BPS_100G"
|
||||
bgp_range = "169.254.1.0/29"
|
||||
bgp_priority = 100
|
||||
interconnect = "projects/my-project/global/interconnects/my-interconnect"
|
||||
vlan_tag = 100
|
||||
}
|
||||
|
||||
description = "test attachment"
|
||||
name = "test-attachment"
|
||||
peer_asn = "65534"
|
||||
|
||||
network = "$networks:my_network"
|
||||
project_id = "$project_ids:my_project"
|
||||
region = "$locations:my_region"
|
||||
|
||||
router_config = {
|
||||
create = false
|
||||
name = "$routers:my_router"
|
||||
}
|
||||
85
tests/modules/net-vlan-attachment/context.yaml
Normal file
85
tests/modules/net-vlan-attachment/context.yaml
Normal file
@@ -0,0 +1,85 @@
|
||||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
values:
|
||||
google_compute_interconnect_attachment.default:
|
||||
admin_enabled: true
|
||||
bandwidth: BPS_100G
|
||||
candidate_cloud_router_ip_address: null
|
||||
candidate_cloud_router_ipv6_address: null
|
||||
candidate_customer_router_ip_address: null
|
||||
candidate_customer_router_ipv6_address: null
|
||||
candidate_subnets:
|
||||
- 169.254.1.0/29
|
||||
description: test attachment
|
||||
effective_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
encryption: NONE
|
||||
interconnect: projects/my-project/global/interconnects/my-interconnect
|
||||
ipsec_internal_addresses: null
|
||||
l2_forwarding: []
|
||||
labels: null
|
||||
mtu: '1500'
|
||||
name: test-attachment
|
||||
project: my-project
|
||||
region: europe-west1
|
||||
router: my-router
|
||||
subnet_length: null
|
||||
terraform_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
timeouts: null
|
||||
type: DEDICATED
|
||||
vlan_tag8021q: 100
|
||||
google_compute_router_interface.default[0]:
|
||||
name: test-attachment-intf
|
||||
private_ip_address: null
|
||||
project: my-project
|
||||
region: europe-west1
|
||||
router: my-router
|
||||
subnetwork: null
|
||||
timeouts: null
|
||||
vpn_tunnel: null
|
||||
google_compute_router_peer.default[0]:
|
||||
advertise_mode: CUSTOM
|
||||
advertised_groups: null
|
||||
advertised_ip_ranges: []
|
||||
advertised_route_priority: 100
|
||||
custom_learned_ip_ranges: []
|
||||
custom_learned_route_priority: null
|
||||
enable: true
|
||||
enable_ipv6: false
|
||||
export_policies: null
|
||||
import_policies: null
|
||||
interface: test-attachment-intf
|
||||
md5_authentication_key: []
|
||||
name: test-attachment-peer
|
||||
peer_asn: 65534
|
||||
project: my-project
|
||||
region: europe-west1
|
||||
router: my-router
|
||||
router_appliance_instance: null
|
||||
timeouts: null
|
||||
zero_advertised_route_priority: null
|
||||
zero_custom_learned_route_priority: false
|
||||
random_id.secret:
|
||||
byte_length: 12
|
||||
keepers: null
|
||||
prefix: null
|
||||
|
||||
counts:
|
||||
google_compute_interconnect_attachment: 1
|
||||
google_compute_router_interface: 1
|
||||
google_compute_router_peer: 1
|
||||
modules: 0
|
||||
random_id: 1
|
||||
17
tests/modules/net-vlan-attachment/tftest.yaml
Normal file
17
tests/modules/net-vlan-attachment/tftest.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copyright 2025 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
module: modules/net-vlan-attachment
|
||||
tests:
|
||||
context:
|
||||
Reference in New Issue
Block a user