From e4f2c68d8b660e1e3ffb03f270a16669a92387c3 Mon Sep 17 00:00:00 2001 From: Luca Prete Date: Sun, 24 May 2026 19:03:56 +0200 Subject: [PATCH] Add context to net-lb-proxy-int (#3988) * net-lb-proxy-int: add context * Update modules/net-lb-proxy-int/README.md * Update modules/net-lb-proxy-int/README.md * Update modules/net-lb-proxy-int/README.md * Update modules/net-lb-proxy-int/README.md * Update modules/net-lb-proxy-int/README.md * Update modules/net-lb-proxy-int/README.md * Update modules/net-lb-proxy-int/README.md * Update modules/net-lb-proxy-int/README.md * Update modules/net-lb-proxy-int/README.md * Update modules/net-lb-proxy-int/README.md --------- Co-authored-by: Julio Castillo --- modules/net-lb-proxy-int/README.md | 79 ++++++++-- modules/net-lb-proxy-int/backend-service.tf | 4 +- modules/net-lb-proxy-int/groups.tf | 4 +- modules/net-lb-proxy-int/health-check.tf | 4 +- modules/net-lb-proxy-int/main.tf | 85 +++++++---- modules/net-lb-proxy-int/variables.tf | 13 ++ .../net_lb_proxy_int/examples/context.yaml | 135 ++++++++++++++++++ 7 files changed, 279 insertions(+), 45 deletions(-) create mode 100644 tests/modules/net_lb_proxy_int/examples/context.yaml diff --git a/modules/net-lb-proxy-int/README.md b/modules/net-lb-proxy-int/README.md index ea0c85389..af1053c4b 100644 --- a/modules/net-lb-proxy-int/README.md +++ b/modules/net-lb-proxy-int/README.md @@ -16,6 +16,7 @@ Due to the complexity of the underlying resources, changes to the configuration - [Hybrid NEG creation](#hybrid-neg-creation) - [Private Service Connect NEG creation](#private-service-connect-neg-creation) - [Internet NEG creation](#internet-neg-creation) + - [Context](#context) - [Deploying changes to load balancer configurations](#deploying-changes-to-load-balancer-configurations) - [Files](#files) - [Variables](#variables) @@ -313,6 +314,57 @@ module "ilb-l7" { # tftest modules=1 resources=6 inventory=internet-neg.yaml e2e ``` +### Context + +The module supports the contexts interpolation. For example: + +```hcl +module "tcp-proxy" { + source = "./fabric/modules/net-lb-proxy-int" + name = "ilb-test" + project_id = "$project_ids:test" + region = "$locations:ew8" + address = "$addresses:test" + backend_service_config = { + backends = [{ + group = "projects/myprj/zones/europe-west1-a/instanceGroups/my-ig" + }] + } + group_configs = { + default = { + zone = "$locations:ew8-b" + instances = [ + "projects/myprj/zones/europe-west1-b/instances/vm-a" + ] + named_ports = { http = 80 } + } + } + vpc_config = { + network = "$networks:test" + subnetwork = "$subnets:test" + } + context = { + addresses = { + test = "10.0.0.10" + } + locations = { + ew8 = "europe-west8" + ew8-b = "europe-west8-b" + } + networks = { + test = "projects/foo-dev-net-spoke-0/global/networks/dev-spoke-0" + } + project_ids = { + test = "foo-test-0" + } + subnets = { + test = "projects/foo-dev-net-spoke-0/regions/europe-west8/subnetworks/gce" + } + } +} +# tftest inventory=context.yaml +``` + ## Deploying changes to load balancer configurations For deploying changes to load balancer configuration please refer to [net-lb-app-ext README.md](../net-lb-app-ext/README.md#deploying-changes-to-load-balancer-configurations) @@ -334,21 +386,22 @@ For deploying changes to load balancer configuration please refer to [net-lb-app | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [name](variables.tf#L208) | Load balancer name. | string | ✓ | | -| [project_id](variables.tf#L277) | Project id. | string | ✓ | | -| [region](variables.tf#L282) | The region where to allocate the ILB resources. | string | ✓ | | -| [vpc_config](variables.tf#L302) | VPC-level configuration. | object({…}) | ✓ | | +| [name](variables.tf#L221) | Load balancer name. | string | ✓ | | +| [project_id](variables.tf#L290) | Project id. | string | ✓ | | +| [region](variables.tf#L295) | The region where to allocate the ILB resources. | string | ✓ | | +| [vpc_config](variables.tf#L315) | VPC-level configuration. | object({…}) | ✓ | | | [address](variables.tf#L17) | Optional IP address used for the forwarding rule. | string | | null | | [backend_service_config](variables.tf#L23) | Backend service level configuration. | object({…}) | | {} | -| [description](variables.tf#L82) | Optional description used for resources. | string | | "Terraform managed." | -| [global_access](variables.tf#L89) | Allow client access from all regions. | bool | | null | -| [group_configs](variables.tf#L95) | Optional unmanaged groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | -| [health_check](variables.tf#L109) | Name of existing health check to use, disables auto-created health check. | string | | null | -| [health_check_config](variables.tf#L115) | Optional auto-created health check configurations, use the output self-link to set it in the auto healing policy. Refer to examples for usage. | object({…}) | | {…} | -| [labels](variables.tf#L202) | Labels set on resources. | map(string) | | {} | -| [neg_configs](variables.tf#L213) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | -| [port](variables.tf#L271) | Port. | number | | 80 | -| [service_attachment](variables.tf#L287) | PSC service attachment. | object({…}) | | null | +| [context](variables.tf#L82) | Context-specific interpolations. | object({…}) | | {} | +| [description](variables.tf#L95) | Optional description used for resources. | string | | "Terraform managed." | +| [global_access](variables.tf#L102) | Allow client access from all regions. | bool | | null | +| [group_configs](variables.tf#L108) | Optional unmanaged groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | +| [health_check](variables.tf#L122) | Name of existing health check to use, disables auto-created health check. | string | | null | +| [health_check_config](variables.tf#L128) | Optional auto-created health check configurations, use the output self-link to set it in the auto healing policy. Refer to examples for usage. | object({…}) | | {…} | +| [labels](variables.tf#L215) | Labels set on resources. | map(string) | | {} | +| [neg_configs](variables.tf#L226) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | +| [port](variables.tf#L284) | Port. | number | | 80 | +| [service_attachment](variables.tf#L300) | PSC service attachment. | object({…}) | | null | ## Outputs diff --git a/modules/net-lb-proxy-int/backend-service.tf b/modules/net-lb-proxy-int/backend-service.tf index 3dac7dd1b..3d92b6637 100644 --- a/modules/net-lb-proxy-int/backend-service.tf +++ b/modules/net-lb-proxy-int/backend-service.tf @@ -36,8 +36,8 @@ locals { resource "google_compute_region_backend_service" "default" { provider = google-beta - project = var.project_id - region = var.region + project = local.project_id + region = local.region name = coalesce(var.backend_service_config.name, var.name) description = var.backend_service_config.description affinity_cookie_ttl_sec = var.backend_service_config.affinity_cookie_ttl_sec diff --git a/modules/net-lb-proxy-int/groups.tf b/modules/net-lb-proxy-int/groups.tf index 382201807..dede20ef5 100644 --- a/modules/net-lb-proxy-int/groups.tf +++ b/modules/net-lb-proxy-int/groups.tf @@ -18,10 +18,10 @@ resource "google_compute_instance_group" "default" { for_each = var.group_configs project = ( each.value.project_id == null - ? var.project_id + ? local.project_id : each.value.project_id ) - zone = each.value.zone + zone = try(local.ctx.locations[each.value.zone], each.value.zone) name = coalesce(each.value.name, "${var.name}-${each.key}") description = each.value.description instances = each.value.instances diff --git a/modules/net-lb-proxy-int/health-check.tf b/modules/net-lb-proxy-int/health-check.tf index 8e44dc5c2..27544eb98 100644 --- a/modules/net-lb-proxy-int/health-check.tf +++ b/modules/net-lb-proxy-int/health-check.tf @@ -31,9 +31,9 @@ locals { resource "google_compute_region_health_check" "default" { provider = google-beta count = local.hc != null ? 1 : 0 - project = var.project_id + project = local.project_id name = coalesce(local.hc.name, var.name) - region = var.region + region = local.region description = local.hc.description check_interval_sec = local.hc.check_interval_sec healthy_threshold = local.hc.healthy_threshold diff --git a/modules/net-lb-proxy-int/main.tf b/modules/net-lb-proxy-int/main.tf index 096ae33ce..fffd49d48 100644 --- a/modules/net-lb-proxy-int/main.tf +++ b/modules/net-lb-proxy-int/main.tf @@ -14,6 +14,19 @@ * limitations under the License. */ +locals { + ctx = { + for k, v in var.context : k => { + for kk, vv in v : "${local.ctx_p}${k}:${kk}" => vv + } + } + ctx_p = "$" + network = lookup(local.ctx.networks, var.vpc_config.network, var.vpc_config.network) + project_id = lookup(local.ctx.project_ids, var.project_id, var.project_id) + region = lookup(local.ctx.locations, var.region, var.region) + subnetwork = lookup(local.ctx.subnets, var.vpc_config.subnetwork, var.vpc_config.subnetwork) +} + locals { # we need keys in the endpoint type to address issue #1055 _neg_endpoints = flatten([ @@ -23,6 +36,11 @@ locals { }) ] ]) + health_check = ( + var.health_check != null + ? var.health_check + : google_compute_region_health_check.default[0].self_link + ) neg_endpoints = { for v in local._neg_endpoints : (v.key) => v } @@ -41,25 +59,24 @@ locals { for k, v in var.neg_configs : k => v if v.psc != null } - health_check = ( - var.health_check != null - ? var.health_check - : google_compute_region_health_check.default[0].self_link - ) } resource "google_compute_forwarding_rule" "default" { - provider = google-beta - project = var.project_id - region = var.region - name = var.name - description = var.description - ip_address = var.address + provider = google-beta + project = local.project_id + region = local.region + name = var.name + description = var.description + ip_address = ( + var.address == null + ? null + : lookup(local.ctx.addresses, var.address, var.address) + ) ip_protocol = "TCP" load_balancing_scheme = "INTERNAL_MANAGED" - network = var.vpc_config.network + network = local.network port_range = var.port - subnetwork = var.vpc_config.subnetwork + subnetwork = local.subnetwork labels = var.labels target = google_compute_region_target_tcp_proxy.default.id # during the preview phase you cannot change this attribute on an existing rule @@ -67,10 +84,10 @@ resource "google_compute_forwarding_rule" "default" { } resource "google_compute_region_target_tcp_proxy" "default" { - project = var.project_id + project = local.project_id name = var.name description = var.description - region = var.region + region = local.region backend_service = google_compute_region_backend_service.default.self_link } @@ -78,22 +95,27 @@ resource "google_compute_network_endpoint_group" "default" { for_each = local.neg_zonal project = ( each.value.project_id == null - ? var.project_id + ? local.project_id : each.value.project_id ) - zone = each.value.zone + zone = try(local.ctx.locations[each.value.zone], each.value.zone) name = "${var.name}-${each.key}" # re-enable once provider properly supports this # default_port = each.value.default_port description = var.description network_endpoint_type = each.value.type network = ( - each.value.network != null ? each.value.network : var.vpc_config.network + each.value.network != null + ? try(local.ctx.networks[each.value.network], each.value.network) + : local.network ) subnetwork = ( each.value.type == "NON_GCP_PRIVATE_IP_PORT" ? null - : coalesce(each.value.subnetwork, var.vpc_config.subnetwork) + : coalesce( + try(local.ctx.subnets[each.value.subnetwork], each.value.subnetwork), + local.subnetwork + ) ) } @@ -108,19 +130,27 @@ resource "google_compute_network_endpoint" "default" { instance = try(each.value.instance, null) ip_address = each.value.ip_address port = each.value.port - zone = each.value.zone + zone = try(local.ctx.locations[each.value.zone], each.value.zone) } resource "google_compute_region_network_endpoint_group" "psc" { for_each = local.neg_regional_psc - project = var.project_id + project = local.project_id region = each.value.psc.region name = "${var.name}-${each.key}" //description = coalesce(each.value.description, var.description) network_endpoint_type = "PRIVATE_SERVICE_CONNECT" psc_target_service = each.value.psc.target_service - network = each.value.psc.network - subnetwork = each.value.psc.subnetwork + network = ( + each.value.psc.network == null + ? null + : try(local.ctx.networks[each.value.psc.network], each.value.psc.network) + ) + subnetwork = ( + each.value.psc.subnetwork == null + ? null + : try(local.ctx.subnets[each.value.psc.subnetwork], each.value.psc.subnetwork) + ) lifecycle { # ignore until https://github.com/hashicorp/terraform-provider-google/issues/20576 is fixed ignore_changes = [psc_data] @@ -147,7 +177,7 @@ locals { resource "google_compute_region_network_endpoint_group" "internet" { for_each = local.neg_internet - project = var.project_id + project = local.project_id name = "${var.name}-${each.key}" region = each.value.internet.region # re-enable once provider properly supports this @@ -176,12 +206,15 @@ resource "google_compute_region_network_endpoint" "internet" { # PSC Producer Service attachments resource "google_compute_service_attachment" "default" { count = var.service_attachment == null ? 0 : 1 - project = var.project_id + project = local.project_id region = var.region name = var.name description = var.description target_service = google_compute_forwarding_rule.default.id - nat_subnets = var.service_attachment.nat_subnets + nat_subnets = [ + for s in var.service_attachment.nat_subnets + : lookup(local.ctx.subnets, s, s) + ] connection_preference = ( var.service_attachment.automatic_connection ? "ACCEPT_AUTOMATIC" diff --git a/modules/net-lb-proxy-int/variables.tf b/modules/net-lb-proxy-int/variables.tf index d4f631a42..12590d16b 100644 --- a/modules/net-lb-proxy-int/variables.tf +++ b/modules/net-lb-proxy-int/variables.tf @@ -79,6 +79,19 @@ variable "backend_service_config" { } } +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), {}) + subnets = optional(map(string), {}) + }) + default = {} + nullable = false +} + variable "description" { description = "Optional description used for resources." type = string diff --git a/tests/modules/net_lb_proxy_int/examples/context.yaml b/tests/modules/net_lb_proxy_int/examples/context.yaml new file mode 100644 index 000000000..201db62ac --- /dev/null +++ b/tests/modules/net_lb_proxy_int/examples/context.yaml @@ -0,0 +1,135 @@ +# 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: + module.tcp-proxy.google_compute_forwarding_rule.default: + all_ports: null + allow_global_access: null + allow_psc_global_access: null + backend_service: null + description: Terraform managed. + ip_address: 10.0.0.10 + ip_collection: null + ip_protocol: TCP + is_mirroring_collector: null + labels: null + load_balancing_scheme: INTERNAL_MANAGED + name: ilb-test + network: projects/foo-dev-net-spoke-0/global/networks/dev-spoke-0 + no_automate_dns_zone: null + port_range: '80' + ports: null + project: foo-test-0 + recreate_closed_psc: false + region: europe-west8 + service_label: null + source_ip_ranges: null + subnetwork: projects/foo-dev-net-spoke-0/regions/europe-west8/subnetworks/gce + timeouts: null + module.tcp-proxy.google_compute_instance_group.default["default"]: + description: Terraform managed. + instances: + - projects/myprj/zones/europe-west1-b/instances/vm-a + name: ilb-test-default + named_port: + - name: http + port: 80 + project: foo-test-0 + timeouts: null + zone: europe-west8-b + module.tcp-proxy.google_compute_region_backend_service.default: + affinity_cookie_ttl_sec: null + backend: + - balancing_mode: UTILIZATION + capacity_scaler: 1 + custom_metrics: [] + description: Terraform managed. + failover: false + group: projects/myprj/zones/europe-west1-a/instanceGroups/my-ig + max_connections: null + max_connections_per_endpoint: null + max_connections_per_instance: null + max_rate: null + max_rate_per_endpoint: null + max_rate_per_instance: null + max_utilization: null + traffic_duration: '' + circuit_breakers: [] + connection_draining_timeout_sec: 300 + connection_tracking_policy: [] + consistent_hash: [] + custom_metrics: [] + description: Terraform managed. + dynamic_forwarding: [] + enable_cdn: null + failover_policy: [] + ha_policy: [] + ip_address_selection_policy: null + load_balancing_scheme: INTERNAL_MANAGED + locality_lb_policy: null + name: ilb-test + network: null + network_pass_through_lb_traffic_policy: [] + outlier_detection: [] + params: [] + project: foo-test-0 + protocol: TCP + region: europe-west8 + security_policy: null + session_affinity: NONE + strong_session_affinity_cookie: [] + subsetting: [] + timeouts: null + tls_settings: [] + module.tcp-proxy.google_compute_region_health_check.default[0]: + check_interval_sec: 5 + description: Terraform managed. + grpc_health_check: [] + grpc_tls_health_check: [] + healthy_threshold: 2 + http2_health_check: [] + http_health_check: [] + https_health_check: [] + name: ilb-test + project: foo-test-0 + region: europe-west8 + ssl_health_check: [] + tcp_health_check: + - port: null + port_name: null + port_specification: USE_SERVING_PORT + proxy_header: NONE + request: null + response: null + timeout_sec: 5 + timeouts: null + unhealthy_threshold: 2 + module.tcp-proxy.google_compute_region_target_tcp_proxy.default: + description: Terraform managed. + name: ilb-test + project: foo-test-0 + proxy_header: NONE + region: europe-west8 + timeouts: null + +counts: + google_compute_forwarding_rule: 1 + google_compute_instance_group: 1 + google_compute_region_backend_service: 1 + google_compute_region_health_check: 1 + google_compute_region_target_tcp_proxy: 1 + modules: 1 + resources: 5 + +outputs: {}