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: {}