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 <jccb@google.com>
This commit is contained in:
Luca Prete
2026-05-24 19:03:56 +02:00
committed by GitHub
parent c24dae395b
commit e4f2c68d8b
7 changed files with 279 additions and 45 deletions

View File

@@ -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. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L277) | Project id. | <code>string</code> | ✓ | |
| [region](variables.tf#L282) | The region where to allocate the ILB resources. | <code>string</code> | ✓ | |
| [vpc_config](variables.tf#L302) | VPC-level configuration. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [name](variables.tf#L221) | Load balancer name. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L290) | Project id. | <code>string</code> | ✓ | |
| [region](variables.tf#L295) | The region where to allocate the ILB resources. | <code>string</code> | ✓ | |
| [vpc_config](variables.tf#L315) | VPC-level configuration. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [address](variables.tf#L17) | Optional IP address used for the forwarding rule. | <code>string</code> | | <code>null</code> |
| [backend_service_config](variables.tf#L23) | Backend service level configuration. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [description](variables.tf#L82) | Optional description used for resources. | <code>string</code> | | <code>&#34;Terraform managed.&#34;</code> |
| [global_access](variables.tf#L89) | Allow client access from all regions. | <code>bool</code> | | <code>null</code> |
| [group_configs](variables.tf#L95) | Optional unmanaged groups to create. Can be referenced in backends via key or outputs. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [health_check](variables.tf#L109) | Name of existing health check to use, disables auto-created health check. | <code>string</code> | | <code>null</code> |
| [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. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#8230;&#125;</code> |
| [labels](variables.tf#L202) | Labels set on resources. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [neg_configs](variables.tf#L213) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [port](variables.tf#L271) | Port. | <code>number</code> | | <code>80</code> |
| [service_attachment](variables.tf#L287) | PSC service attachment. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [context](variables.tf#L82) | Context-specific interpolations. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [description](variables.tf#L95) | Optional description used for resources. | <code>string</code> | | <code>&#34;Terraform managed.&#34;</code> |
| [global_access](variables.tf#L102) | Allow client access from all regions. | <code>bool</code> | | <code>null</code> |
| [group_configs](variables.tf#L108) | Optional unmanaged groups to create. Can be referenced in backends via key or outputs. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [health_check](variables.tf#L122) | Name of existing health check to use, disables auto-created health check. | <code>string</code> | | <code>null</code> |
| [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. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#8230;&#125;</code> |
| [labels](variables.tf#L215) | Labels set on resources. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [neg_configs](variables.tf#L226) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [port](variables.tf#L284) | Port. | <code>number</code> | | <code>80</code> |
| [service_attachment](variables.tf#L300) | PSC service attachment. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
## Outputs

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

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