Add Multi-Region support to cloud-run-v2 module (#4022)
* Add Multi-Region support to cloud-run-v2 module * Support context expansion for multi_region_settings regions * Fix multi_region_regions formatting line length
This commit is contained in:
@@ -21,6 +21,7 @@ Cloud Run Services and Jobs, with support for IAM roles and Eventarc trigger cre
|
||||
- [Tag bindings](#tag-bindings)
|
||||
- [IAP Configuration](#iap-configuration)
|
||||
- [Adding GPUs](#adding-gpus)
|
||||
- [Multi-Region Service](#multi-region-service)
|
||||
- [Variables](#variables)
|
||||
- [Outputs](#outputs)
|
||||
- [Fixtures](#fixtures)
|
||||
@@ -976,6 +977,30 @@ module "worker" {
|
||||
}
|
||||
# tftest inventory=gpu-workerpool.yaml e2e
|
||||
```
|
||||
|
||||
## Multi-Region Service
|
||||
|
||||
```hcl
|
||||
module "cloud_run" {
|
||||
source = "./fabric/modules/cloud-run-v2"
|
||||
project_id = var.project_id
|
||||
region = "global"
|
||||
name = "example-mr"
|
||||
containers = {
|
||||
hello = {
|
||||
image = "us-docker.pkg.dev/cloudrun/container/hello"
|
||||
}
|
||||
}
|
||||
service_config = {
|
||||
ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
|
||||
multi_region_settings = {
|
||||
regions = ["europe-west8", "europe-west1"]
|
||||
}
|
||||
}
|
||||
deletion_protection = false
|
||||
}
|
||||
# tftest inventory=multiregion.yaml
|
||||
```
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Variables
|
||||
|
||||
@@ -996,11 +1021,11 @@ module "worker" {
|
||||
| [revision](variables.tf#L197) | Revision template configurations. | <code>object({…})</code> | | <code>{}</code> |
|
||||
| [service_account_config](variables-serviceaccount.tf#L17) | Service account configurations. | <code>object({…})</code> | | <code>{}</code> |
|
||||
| [service_config](variables.tf#L264) | Cloud Run service specific configuration options. | <code>object({…})</code> | | <code>{}</code> |
|
||||
| [tag_bindings](variables.tf#L327) | Tag bindings for this service, in key => tag value id format. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [type](variables.tf#L334) | Type of Cloud Run resource to deploy: JOB, SERVICE or WORKERPOOL. | <code>string</code> | | <code>"SERVICE"</code> |
|
||||
| [volumes](variables.tf#L344) | Named volumes in containers in name => attributes format. | <code>map(object({…}))</code> | | <code>{}</code> |
|
||||
| [tag_bindings](variables.tf#L330) | Tag bindings for this service, in key => tag value id format. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [type](variables.tf#L337) | Type of Cloud Run resource to deploy: JOB, SERVICE or WORKERPOOL. | <code>string</code> | | <code>"SERVICE"</code> |
|
||||
| [volumes](variables.tf#L347) | Named volumes in containers in name => attributes format. | <code>map(object({…}))</code> | | <code>{}</code> |
|
||||
| [vpc_connector_create](variables-vpcconnector.tf#L17) | VPC connector network configuration. Must be provided if new VPC connector is being created. | <code>object({…})</code> | | <code>null</code> |
|
||||
| [workerpool_config](variables.tf#L378) | Cloud Run Worker Pool specific configuration. | <code>object({…})</code> | | <code>{}</code> |
|
||||
| [workerpool_config](variables.tf#L381) | Cloud Run Worker Pool specific configuration. | <code>object({…})</code> | | <code>{}</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
||||
@@ -45,6 +45,14 @@ locals {
|
||||
|
||||
location = lookup(local.ctx.locations, var.region, var.region)
|
||||
project_id = lookup(local.ctx.project_ids, var.project_id, var.project_id)
|
||||
multi_region_regions = (
|
||||
try(var.service_config.multi_region_settings.regions, null) == null
|
||||
? null
|
||||
: [
|
||||
for r in var.service_config.multi_region_settings.regions :
|
||||
lookup(local.ctx.locations, r, r)
|
||||
]
|
||||
)
|
||||
|
||||
revision_name = (
|
||||
var.revision.name == null ? null : "${var.name}-${var.revision.name}"
|
||||
|
||||
@@ -28,6 +28,13 @@ resource "google_cloud_run_v2_service" "service" {
|
||||
deletion_protection = var.deletion_protection
|
||||
iap_enabled = var.service_config.iap_config != null
|
||||
|
||||
dynamic "multi_region_settings" {
|
||||
for_each = local.multi_region_regions == null ? [] : [""]
|
||||
content {
|
||||
regions = local.multi_region_regions
|
||||
}
|
||||
}
|
||||
|
||||
template {
|
||||
labels = var.revision.labels
|
||||
encryption_key = var.encryption_key
|
||||
|
||||
@@ -28,6 +28,13 @@ resource "google_cloud_run_v2_service" "service_unmanaged" {
|
||||
deletion_protection = var.deletion_protection
|
||||
iap_enabled = var.service_config.iap_config != null
|
||||
|
||||
dynamic "multi_region_settings" {
|
||||
for_each = local.multi_region_regions == null ? [] : [""]
|
||||
content {
|
||||
regions = local.multi_region_regions
|
||||
}
|
||||
}
|
||||
|
||||
template {
|
||||
labels = var.revision.labels
|
||||
encryption_key = var.encryption_key
|
||||
|
||||
@@ -286,6 +286,9 @@ variable "service_config" {
|
||||
ingress = optional(string, null)
|
||||
invoker_iam_disabled = optional(bool, false)
|
||||
max_concurrency = optional(number)
|
||||
multi_region_settings = optional(object({
|
||||
regions = list(string)
|
||||
}), null)
|
||||
scaling = optional(object({
|
||||
max_instance_count = optional(number)
|
||||
min_instance_count = optional(number)
|
||||
|
||||
@@ -67,3 +67,9 @@ tag_bindings = {
|
||||
baz = "$tag_values:test/one"
|
||||
foo = "$${projects[\"test-00\"].test}/cc-123"
|
||||
}
|
||||
service_config = {
|
||||
multi_region_settings = {
|
||||
regions = ["$locations:ew8", "europe-west1"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Copyright 2025 Google LLC
|
||||
# Copyright 2026 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
|
||||
# https://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,
|
||||
@@ -21,6 +21,7 @@ values:
|
||||
client_version: null
|
||||
custom_audiences: null
|
||||
default_uri_disabled: null
|
||||
deletion_policy: DELETE
|
||||
deletion_protection: true
|
||||
description: null
|
||||
effective_labels:
|
||||
@@ -29,7 +30,10 @@ values:
|
||||
invoker_iam_disabled: false
|
||||
labels: null
|
||||
location: europe-west8
|
||||
multi_region_settings: []
|
||||
multi_region_settings:
|
||||
- regions:
|
||||
- europe-west8
|
||||
- europe-west1
|
||||
name: test-run-context
|
||||
project: foo-test-0
|
||||
template:
|
||||
@@ -38,6 +42,7 @@ values:
|
||||
encryption_key: null
|
||||
execution_environment: EXECUTION_ENVIRONMENT_GEN1
|
||||
gpu_zonal_redundancy_disabled: null
|
||||
health_check_disabled: null
|
||||
labels: null
|
||||
node_selector: []
|
||||
revision: null
|
||||
@@ -61,6 +66,7 @@ values:
|
||||
google_service_account.service_account[0]:
|
||||
account_id: test-run-context
|
||||
create_ignore_already_exists: null
|
||||
deletion_policy: DELETE
|
||||
description: null
|
||||
disabled: false
|
||||
display_name: test-run-context
|
||||
@@ -68,7 +74,23 @@ values:
|
||||
member: serviceAccount:test-run-context@foo-test-0.iam.gserviceaccount.com
|
||||
project: foo-test-0
|
||||
timeouts: null
|
||||
google_tags_location_tag_binding.binding["bar"]:
|
||||
deletion_policy: DELETE
|
||||
location: europe-west8
|
||||
tag_value: tagValues/1234567891
|
||||
timeouts: null
|
||||
google_tags_location_tag_binding.binding["baz"]:
|
||||
deletion_policy: DELETE
|
||||
location: europe-west8
|
||||
tag_value: tagValues/1234567890
|
||||
timeouts: null
|
||||
google_tags_location_tag_binding.binding["foo"]:
|
||||
deletion_policy: DELETE
|
||||
location: europe-west8
|
||||
tag_value: foo-test-0/dynamic_test/cc-123
|
||||
timeouts: null
|
||||
google_vpc_access_connector.connector[0]:
|
||||
deletion_policy: DELETE
|
||||
ip_cidr_range: 10.10.20.0/28
|
||||
machine_type: e2-micro
|
||||
max_instances: 10
|
||||
@@ -79,21 +101,27 @@ values:
|
||||
region: europe-west8
|
||||
subnet: []
|
||||
timeouts: null
|
||||
google_tags_location_tag_binding.binding["bar"]:
|
||||
location: europe-west8
|
||||
tag_value: tagValues/1234567891
|
||||
timeouts: null
|
||||
google_tags_location_tag_binding.binding["baz"]:
|
||||
location: europe-west8
|
||||
tag_value: tagValues/1234567890
|
||||
timeouts: null
|
||||
google_tags_location_tag_binding.binding["foo"]:
|
||||
location: europe-west8
|
||||
tag_value: foo-test-0/dynamic_test/cc-123
|
||||
timeouts: null
|
||||
|
||||
counts:
|
||||
google_cloud_run_v2_service: 1
|
||||
google_cloud_run_v2_service_iam_binding: 1
|
||||
google_project_iam_member: 1
|
||||
google_service_account: 1
|
||||
google_tags_location_tag_binding: 3
|
||||
google_vpc_access_connector: 1
|
||||
modules: 0
|
||||
resources: 8
|
||||
|
||||
outputs:
|
||||
id: __missing__
|
||||
invoke_command: __missing__
|
||||
job: null
|
||||
resource: __missing__
|
||||
resource_name: __missing__
|
||||
service: __missing__
|
||||
service_account: __missing__
|
||||
service_account_email: test-run-context@foo-test-0.iam.gserviceaccount.com
|
||||
service_account_iam_email: serviceAccount:test-run-context@foo-test-0.iam.gserviceaccount.com
|
||||
service_name: __missing__
|
||||
service_uri: __missing__
|
||||
vpc_connector: __missing__
|
||||
|
||||
99
tests/modules/cloud_run_v2/examples/multiregion.yaml
Normal file
99
tests/modules/cloud_run_v2/examples/multiregion.yaml
Normal file
@@ -0,0 +1,99 @@
|
||||
# Copyright 2026 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
|
||||
#
|
||||
# https://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.cloud_run.google_cloud_run_v2_service.service[0]:
|
||||
annotations: null
|
||||
binary_authorization: []
|
||||
build_config: []
|
||||
client: null
|
||||
client_version: null
|
||||
custom_audiences: null
|
||||
default_uri_disabled: null
|
||||
deletion_policy: DELETE
|
||||
deletion_protection: false
|
||||
description: null
|
||||
effective_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
iap_enabled: false
|
||||
ingress: INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER
|
||||
invoker_iam_disabled: false
|
||||
labels: null
|
||||
location: global
|
||||
multi_region_settings:
|
||||
- regions:
|
||||
- europe-west8
|
||||
- europe-west1
|
||||
name: example-mr
|
||||
project: project-id
|
||||
template:
|
||||
- annotations: null
|
||||
containers:
|
||||
- args: null
|
||||
base_image_uri: null
|
||||
command: null
|
||||
depends_on: null
|
||||
env: []
|
||||
image: us-docker.pkg.dev/cloudrun/container/hello
|
||||
liveness_probe: []
|
||||
name: hello
|
||||
readiness_probe: []
|
||||
source_code: []
|
||||
volume_mounts: []
|
||||
working_dir: null
|
||||
encryption_key: null
|
||||
execution_environment: EXECUTION_ENVIRONMENT_GEN1
|
||||
gpu_zonal_redundancy_disabled: null
|
||||
health_check_disabled: null
|
||||
labels: null
|
||||
node_selector: []
|
||||
revision: null
|
||||
service_account: example-mr@project-id.iam.gserviceaccount.com
|
||||
service_mesh: []
|
||||
session_affinity: null
|
||||
volumes: []
|
||||
vpc_access: []
|
||||
terraform_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
timeouts: null
|
||||
module.cloud_run.google_project_iam_member.default["roles/logging.logWriter"]:
|
||||
condition: []
|
||||
member: serviceAccount:example-mr@project-id.iam.gserviceaccount.com
|
||||
project: project-id
|
||||
role: roles/logging.logWriter
|
||||
module.cloud_run.google_project_iam_member.default["roles/monitoring.metricWriter"]:
|
||||
condition: []
|
||||
member: serviceAccount:example-mr@project-id.iam.gserviceaccount.com
|
||||
project: project-id
|
||||
role: roles/monitoring.metricWriter
|
||||
module.cloud_run.google_service_account.service_account[0]:
|
||||
account_id: example-mr
|
||||
create_ignore_already_exists: null
|
||||
deletion_policy: DELETE
|
||||
description: null
|
||||
disabled: false
|
||||
display_name: example-mr
|
||||
email: example-mr@project-id.iam.gserviceaccount.com
|
||||
member: serviceAccount:example-mr@project-id.iam.gserviceaccount.com
|
||||
project: project-id
|
||||
timeouts: null
|
||||
|
||||
counts:
|
||||
google_cloud_run_v2_service: 1
|
||||
google_project_iam_member: 2
|
||||
google_service_account: 1
|
||||
modules: 1
|
||||
resources: 4
|
||||
|
||||
outputs: {}
|
||||
15
tests/modules/cloud_run_v2/multiregion.tfvars
Normal file
15
tests/modules/cloud_run_v2/multiregion.tfvars
Normal file
@@ -0,0 +1,15 @@
|
||||
name = "test-run-multiregion"
|
||||
project_id = "test-project"
|
||||
region = "global"
|
||||
|
||||
containers = {
|
||||
first = {
|
||||
image = "gcr.io/cloudrun/hello"
|
||||
}
|
||||
}
|
||||
|
||||
service_config = {
|
||||
multi_region_settings = {
|
||||
regions = ["europe-west8", "europe-west1"]
|
||||
}
|
||||
}
|
||||
110
tests/modules/cloud_run_v2/multiregion.yaml
Normal file
110
tests/modules/cloud_run_v2/multiregion.yaml
Normal file
@@ -0,0 +1,110 @@
|
||||
# Copyright 2026 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
|
||||
#
|
||||
# https://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_cloud_run_v2_service.service[0]:
|
||||
annotations: null
|
||||
binary_authorization: []
|
||||
build_config: []
|
||||
client: null
|
||||
client_version: null
|
||||
custom_audiences: null
|
||||
default_uri_disabled: null
|
||||
deletion_policy: DELETE
|
||||
deletion_protection: true
|
||||
description: null
|
||||
effective_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
iap_enabled: false
|
||||
invoker_iam_disabled: false
|
||||
labels: null
|
||||
location: global
|
||||
multi_region_settings:
|
||||
- regions:
|
||||
- europe-west8
|
||||
- europe-west1
|
||||
name: test-run-multiregion
|
||||
project: test-project
|
||||
template:
|
||||
- annotations: null
|
||||
containers:
|
||||
- args: null
|
||||
base_image_uri: null
|
||||
command: null
|
||||
depends_on: null
|
||||
env: []
|
||||
image: gcr.io/cloudrun/hello
|
||||
liveness_probe: []
|
||||
name: first
|
||||
readiness_probe: []
|
||||
source_code: []
|
||||
volume_mounts: []
|
||||
working_dir: null
|
||||
encryption_key: null
|
||||
execution_environment: EXECUTION_ENVIRONMENT_GEN1
|
||||
gpu_zonal_redundancy_disabled: null
|
||||
health_check_disabled: null
|
||||
labels: null
|
||||
node_selector: []
|
||||
revision: null
|
||||
service_account: test-run-multiregion@test-project.iam.gserviceaccount.com
|
||||
service_mesh: []
|
||||
session_affinity: null
|
||||
volumes: []
|
||||
vpc_access: []
|
||||
terraform_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
timeouts: null
|
||||
google_project_iam_member.default["roles/logging.logWriter"]:
|
||||
condition: []
|
||||
member: serviceAccount:test-run-multiregion@test-project.iam.gserviceaccount.com
|
||||
project: test-project
|
||||
role: roles/logging.logWriter
|
||||
google_project_iam_member.default["roles/monitoring.metricWriter"]:
|
||||
condition: []
|
||||
member: serviceAccount:test-run-multiregion@test-project.iam.gserviceaccount.com
|
||||
project: test-project
|
||||
role: roles/monitoring.metricWriter
|
||||
google_service_account.service_account[0]:
|
||||
account_id: test-run-multiregion
|
||||
create_ignore_already_exists: null
|
||||
deletion_policy: DELETE
|
||||
description: null
|
||||
disabled: false
|
||||
display_name: test-run-multiregion
|
||||
email: test-run-multiregion@test-project.iam.gserviceaccount.com
|
||||
member: serviceAccount:test-run-multiregion@test-project.iam.gserviceaccount.com
|
||||
project: test-project
|
||||
timeouts: null
|
||||
|
||||
counts:
|
||||
google_cloud_run_v2_service: 1
|
||||
google_project_iam_member: 2
|
||||
google_service_account: 1
|
||||
modules: 0
|
||||
resources: 4
|
||||
|
||||
outputs:
|
||||
id: __missing__
|
||||
invoke_command: __missing__
|
||||
job: null
|
||||
resource: __missing__
|
||||
resource_name: __missing__
|
||||
service: __missing__
|
||||
service_account: __missing__
|
||||
service_account_email: test-run-multiregion@test-project.iam.gserviceaccount.com
|
||||
service_account_iam_email: serviceAccount:test-run-multiregion@test-project.iam.gserviceaccount.com
|
||||
service_name: __missing__
|
||||
service_uri: __missing__
|
||||
vpc_connector: null
|
||||
@@ -18,3 +18,5 @@ tests:
|
||||
context-subnet:
|
||||
context-subnet-project:
|
||||
vpcconnector:
|
||||
multiregion:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user