Skip to content

Commit 6200076

Browse files
authored
Feat: support for internal cross-regional load balancer (#490)
1 parent 3b10504 commit 6200076

File tree

22 files changed

+458
-19
lines changed

22 files changed

+458
-19
lines changed

build/int.cloudbuild.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,22 @@ steps:
127127
- verify lb-http-separate-frontend-and-backend
128128
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
129129
args: ['/bin/bash', '-c', 'cft test run TestSeparateFrontendAndBackend --stage teardown --verbose']
130+
# Internal cross regional http load balancer with cloud-run
131+
- id: apply internal-lb-http
132+
waitFor:
133+
- create
134+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
135+
args: ['/bin/bash', '-c', 'cft test run TestInternalLbCloudRun --stage apply --verbose']
136+
- id: verify internal-lb-http
137+
waitFor:
138+
- apply internal-lb-http
139+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
140+
args: ['/bin/bash', '-c', 'sleep 360 && cft test run TestInternalLbCloudRun --stage verify --verbose']
141+
- id: teardown internal-lb-http
142+
waitFor:
143+
- verify internal-lb-http
144+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
145+
args: ['/bin/bash', '-c', 'cft test run TestInternalLbCloudRun --stage teardown --verbose']
130146
tags:
131147
- 'ci'
132148
- 'integration'
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
provider "google" {
18+
project = var.project_id
19+
}
20+
21+
provider "google-beta" {
22+
project = var.project_id
23+
}
24+
25+
module "internal-lb-network" {
26+
source = "terraform-google-modules/network/google//modules/vpc"
27+
version = "~> 10.0.0"
28+
project_id = var.project_id
29+
network_name = "int-lb-network"
30+
auto_create_subnetworks = false
31+
}
32+
33+
module "internal-lb-subnet" {
34+
source = "terraform-google-modules/network/google//modules/subnets"
35+
version = "~> 10.0.0"
36+
37+
subnets = [
38+
{
39+
subnet_name = "int-lb-subnet-a"
40+
subnet_ip = "10.1.2.0/24"
41+
subnet_region = "us-east1"
42+
},
43+
{
44+
subnet_name = "int-lb-proxy-only-subnet-a"
45+
subnet_ip = "10.129.0.0/23"
46+
subnet_region = "us-east1"
47+
purpose = "GLOBAL_MANAGED_PROXY"
48+
role = "ACTIVE"
49+
},
50+
{
51+
subnet_name = "int-lb-subnet-b"
52+
subnet_ip = "10.1.3.0/24"
53+
subnet_region = "us-south1"
54+
},
55+
{
56+
subnet_name = "int-lb-proxy-only-subnet-b",
57+
subnet_ip = "10.130.0.0/23"
58+
subnet_region = "us-south1"
59+
purpose = "GLOBAL_MANAGED_PROXY"
60+
role = "ACTIVE"
61+
}
62+
]
63+
64+
network_name = module.internal-lb-network.network_name
65+
project_id = var.project_id
66+
depends_on = [module.internal-lb-network]
67+
}
68+
69+
module "backend-service-region-a" {
70+
source = "GoogleCloudPlatform/cloud-run/google//modules/v2"
71+
version = "~> 0.16.3"
72+
project_id = var.project_id
73+
location = "us-central1"
74+
service_name = "bs-a"
75+
containers = [{ "container_name" = "", "container_image" = "gcr.io/cloudrun/hello" }]
76+
members = ["allUsers"]
77+
ingress = "INGRESS_TRAFFIC_INTERNAL_ONLY"
78+
cloud_run_deletion_protection = false
79+
enable_prometheus_sidecar = false
80+
}
81+
82+
module "backend-service-region-b" {
83+
source = "GoogleCloudPlatform/cloud-run/google//modules/v2"
84+
version = "~> 0.16.3"
85+
project_id = var.project_id
86+
location = "us-west1"
87+
service_name = "bs-b"
88+
containers = [{ "container_name" = "", "container_image" = "gcr.io/cloudrun/hello" }]
89+
members = ["allUsers"]
90+
ingress = "INGRESS_TRAFFIC_INTERNAL_ONLY"
91+
cloud_run_deletion_protection = false
92+
enable_prometheus_sidecar = false
93+
}
94+
95+
module "internal-lb-http-backend" {
96+
source = "terraform-google-modules/lb-http/google//modules/backend"
97+
version = "~> 12.0"
98+
99+
project_id = var.project_id
100+
name = "int-lb-http-backend"
101+
enable_cdn = false
102+
load_balancing_scheme = "INTERNAL_MANAGED"
103+
locality_lb_policy = "RANDOM"
104+
serverless_neg_backends = [
105+
{ region : "us-central1", type : "cloud-run", service_name : module.backend-service-region-a.service_name },
106+
{ region : "us-west1", type : "cloud-run", service_name : module.backend-service-region-b.service_name }
107+
]
108+
}
109+
110+
module "internal-lb-http-frontend" {
111+
source = "terraform-google-modules/lb-http/google//modules/frontend"
112+
version = "~> 12.0"
113+
114+
project_id = var.project_id
115+
name = "int-lb-http-frontend"
116+
url_map_input = module.internal-lb-http-backend.backend_service_info
117+
network = module.internal-lb-network.network_name
118+
load_balancing_scheme = "INTERNAL_MANAGED"
119+
internal_forwarding_rules_config = [
120+
{
121+
"region" : "us-east1",
122+
"subnetwork" : module.internal-lb-subnet.subnets["us-east1/int-lb-subnet-a"].id
123+
},
124+
{
125+
"region" : "us-south1",
126+
"subnetwork" : module.internal-lb-subnet.subnets["us-south1/int-lb-subnet-b"].id
127+
}
128+
]
129+
}
130+
131+
resource "google_vpc_access_connector" "internal_lb_vpc_connector" {
132+
provider = google-beta
133+
project = var.project_id
134+
name = "int-lb-vpc-connector"
135+
region = "us-east1"
136+
ip_cidr_range = "10.8.0.0/28"
137+
network = module.internal-lb-network.network_name
138+
max_throughput = 500
139+
min_throughput = 300
140+
}
141+
142+
module "frontend-service-a" {
143+
source = "GoogleCloudPlatform/cloud-run/google//modules/v2"
144+
version = "~> 0.16.3"
145+
project_id = var.project_id
146+
location = "us-east1"
147+
service_name = "fs-a"
148+
containers = [{ "env_vars" : { "TARGET_IP" : module.internal-lb-http-frontend.ip_address_internal_managed_http[0] }, "ports" = { "container_port" = 80, "name" = "http1" }, "container_name" = "", "container_image" = "gcr.io/design-center-container-repo/redirect-traffic:latest-2002" }]
149+
members = ["allUsers"]
150+
vpc_access = {
151+
connector = google_vpc_access_connector.internal_lb_vpc_connector.id
152+
egress = "ALL_TRAFFIC"
153+
}
154+
ingress = "INGRESS_TRAFFIC_ALL"
155+
cloud_run_deletion_protection = false
156+
enable_prometheus_sidecar = false
157+
depends_on = [google_vpc_access_connector.internal_lb_vpc_connector]
158+
}
159+
160+
module "frontend-service-b" {
161+
source = "GoogleCloudPlatform/cloud-run/google//modules/v2"
162+
version = "~> 0.16.3"
163+
project_id = var.project_id
164+
location = "us-east1"
165+
service_name = "fs-b"
166+
containers = [{ "env_vars" : { "TARGET_IP" : module.internal-lb-http-frontend.ip_address_internal_managed_http[1] }, "ports" = { "container_port" = 80, "name" = "http1" }, "container_name" = "", "container_image" = "gcr.io/design-center-container-repo/redirect-traffic:latest-2002" }]
167+
members = ["allUsers"]
168+
vpc_access = {
169+
connector = google_vpc_access_connector.internal_lb_vpc_connector.id
170+
egress = "ALL_TRAFFIC"
171+
}
172+
ingress = "INGRESS_TRAFFIC_ALL"
173+
cloud_run_deletion_protection = false
174+
enable_prometheus_sidecar = false
175+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
output "external_cloudrun_uris" {
18+
description = "List of URIs for the frontend Cloud Run services"
19+
value = [module.frontend-service-a.service_uri, module.frontend-service-b.service_uri]
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# HTTP Internal Regional Load Balancer Example
2+
3+
This example creates a simple application with below components.
4+
5+
* *Frontend Service*: Two cloud-run services to send request to internal cross-regional load balancers. The cloud-run service uses VPC access connector to send the request to the internal load balancer.
6+
* *Internal Load Balancer*: An internal cross-regional load balancer to distribute traffic to internal cloud run services.
7+
* *Backend Service*: Two cloud-run services to run the actual application code. These can be accessed within internal traffic. The internal Application Load Balancer is considered internal traffic.
8+
9+
10+
The `google_compute_backend_service` and its dependencies are created as part of `backend` module.
11+
The forwarding rules and its dependecies are created as part of `frontend` module.
12+
13+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
14+
## Inputs
15+
16+
| Name | Description | Type | Default | Required |
17+
|------|-------------|------|---------|:--------:|
18+
| project\_id | n/a | `string` | n/a | yes |
19+
20+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
variable "project_id" {
18+
type = string
19+
}

metadata.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ spec:
5858
location: examples/https-gke
5959
- name: https-redirect
6060
location: examples/https-redirect
61+
- name: internal-lb-cloud-run
62+
location: examples/internal-lb-cloud-run
6163
- name: lb-http-separate-frontend-and-backend
6264
location: examples/lb-http-separate-frontend-and-backend
6365
- name: mig-nat-http-lb
@@ -338,6 +340,8 @@ spec:
338340
- roles/run.admin
339341
- roles/iam.serviceAccountUser
340342
- roles/certificatemanager.owner
343+
- roles/vpcaccess.admin
344+
- roles/iam.serviceAccountAdmin
341345
services:
342346
- cloudresourcemanager.googleapis.com
343347
- storage-api.googleapis.com
@@ -346,6 +350,7 @@ spec:
346350
- run.googleapis.com
347351
- iam.googleapis.com
348352
- certificatemanager.googleapis.com
353+
- vpcaccess.googleapis.com
349354
providerVersions:
350355
- source: hashicorp/google
351356
version: ">= 6.0, < 7"

modules/backend/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ This module creates `google_compute_backend_service` resource and its dependenci
2121
| health\_check | Input for creating HttpHealthCheck or HttpsHealthCheck resource for health checking this BackendService. A health check must be specified unless the backend service uses an internet or serverless NEG as a backend. | <pre>object({<br> host = optional(string, null)<br> request_path = optional(string, null)<br> request = optional(string, null)<br> response = optional(string, null)<br> port = optional(number, null)<br> port_name = optional(string, null)<br> proxy_header = optional(string, null)<br> port_specification = optional(string, null)<br> protocol = optional(string, null)<br> check_interval_sec = optional(number, 5)<br> timeout_sec = optional(number, 5)<br> healthy_threshold = optional(number, 2)<br> unhealthy_threshold = optional(number, 2)<br> logging = optional(bool, false)<br> })</pre> | `null` | no |
2222
| host\_path\_mappings | The list of host/path for which traffic could be sent to the backend service | <pre>list(object({<br> host = string<br> path = string<br> }))</pre> | <pre>[<br> {<br> "host": "*",<br> "path": "/*"<br> }<br>]</pre> | no |
2323
| iap\_config | Settings for enabling Cloud Identity Aware Proxy Structure. | <pre>object({<br> enable = bool<br> oauth2_client_id = optional(string)<br> oauth2_client_secret = optional(string)<br> })</pre> | <pre>{<br> "enable": false<br>}</pre> | no |
24-
| load\_balancing\_scheme | Load balancing scheme type (EXTERNAL for classic external load balancer, EXTERNAL\_MANAGED for Envoy-based load balancer, and INTERNAL\_SELF\_MANAGED for traffic director). | `string` | `"EXTERNAL_MANAGED"` | no |
24+
| load\_balancing\_scheme | Load balancing scheme type (EXTERNAL for classic external load balancer, EXTERNAL\_MANAGED for Envoy-based load balancer, INTERNAL\_MANAGED for internal load balancer and INTERNAL\_SELF\_MANAGED for traffic director) | `string` | `"EXTERNAL_MANAGED"` | no |
2525
| locality\_lb\_policy | The load balancing algorithm used within the scope of the locality. | `string` | `null` | no |
2626
| log\_config | This field denotes the logging options for the load balancer traffic served by this backend service. If logging is enabled, logs will be exported to Stackdriver. | <pre>object({<br> enable = bool<br> sample_rate = number<br> })</pre> | <pre>{<br> "enable": true,<br> "sample_rate": 1<br>}</pre> | no |
2727
| name | Name for the backend service. | `string` | n/a | yes |

modules/backend/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ resource "google_compute_backend_service" "default" {
2828
description = var.description
2929
connection_draining_timeout_sec = var.connection_draining_timeout_sec
3030
enable_cdn = var.enable_cdn
31-
compression_mode = var.compression_mode
31+
compression_mode = var.load_balancing_scheme == "INTERNAL_SELF_MANAGED" || var.load_balancing_scheme == "INTERNAL_MANAGED" ? null : var.compression_mode
3232
custom_request_headers = var.custom_request_headers
3333
custom_response_headers = var.custom_response_headers
3434
session_affinity = var.session_affinity

modules/backend/metadata.display.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ spec:
7777
load_balancing_scheme:
7878
name: load_balancing_scheme
7979
title: Load Balancing Scheme
80+
enumValueLabels:
81+
- label: EXTERNAL_MANAGED
82+
value: EXTERNAL_MANAGED
83+
- label: INTERNAL_MANAGED
84+
value: INTERNAL_MANAGED
8085
locality_lb_policy:
8186
name: locality_lb_policy
8287
title: Locality Lb Policy

modules/backend/metadata.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ spec:
5050
location: examples/https-gke
5151
- name: https-redirect
5252
location: examples/https-redirect
53+
- name: internal-lb-cloud-run
54+
location: examples/internal-lb-cloud-run
5355
- name: lb-http-separate-frontend-and-backend
5456
location: examples/lb-http-separate-frontend-and-backend
5557
- name: mig-nat-http-lb
@@ -77,7 +79,7 @@ spec:
7779
varType: string
7880
required: true
7981
- name: load_balancing_scheme
80-
description: Load balancing scheme type (EXTERNAL for classic external load balancer, EXTERNAL_MANAGED for Envoy-based load balancer, and INTERNAL_SELF_MANAGED for traffic director).
82+
description: Load balancing scheme type (EXTERNAL for classic external load balancer, EXTERNAL_MANAGED for Envoy-based load balancer, INTERNAL_MANAGED for internal load balancer and INTERNAL_SELF_MANAGED for traffic director)
8183
varType: string
8284
defaultValue: EXTERNAL_MANAGED
8385
- name: protocol
@@ -305,6 +307,8 @@ spec:
305307
- roles/run.admin
306308
- roles/iam.serviceAccountUser
307309
- roles/certificatemanager.owner
310+
- roles/vpcaccess.admin
311+
- roles/iam.serviceAccountAdmin
308312
services:
309313
- cloudresourcemanager.googleapis.com
310314
- storage-api.googleapis.com
@@ -313,6 +317,7 @@ spec:
313317
- run.googleapis.com
314318
- iam.googleapis.com
315319
- certificatemanager.googleapis.com
320+
- vpcaccess.googleapis.com
316321
providerVersions:
317322
- source: hashicorp/google
318323
version: ">= 6.0, < 7"

0 commit comments

Comments
 (0)