Terraform 1.2.0:多域名Cloud Run部署的代码复用与资源引用问题
问题描述
我已为两个域名部署了带负载均衡的Cloud Run应用并正常运行,现需将该部署扩展至更多域名。因资源配置逻辑一致,遇到以下问题:
- 已通过
for_each解决代码重复问题,但仍需处理域名特定值(如location)的映射,当前变量配置报错Cannot include the given value in a string template: string required; - 不知如何在其他资源中引用通过
for_each创建的Cloud Run资源。
原重复代码示例
resource "google_cloud_run_service" "cr_domain1" { name = "cr-domain1" location = "europe-west6" project = "my_project" template { ... } } resource "google_cloud_run_service" "cr_domain2" { name = "cr-domain2" location = "europe-southwest1" project = "my_project" template { ... } }
优化后代码(含问题)
resource "google_cloud_run_service" "cr" { for_each = toset( ["domain1", "domain2"] ) name = "cr-${each_key}" location = "tdb" # 需配置域名特定location project = "my_project" template { ... } }
尝试的变量配置(报错)
variable "cr_location" { type = list(object({ domain1 = string domain2 = string })) default = [{ domain1 = "europe-west6" domain2 = "europe-southwest1" }] } resource "google_cloud_run_service" "cr" { for_each = toset( ["domain1", "domain2"] ) name = "cr-${each_key}" location = "${var.cr_location[0]}.${each.key}" project = "my_project" template { ... } }
预期效果:domain1对应europe-west6,domain2对应europe-southwest1。
资源引用问题示例
原负载均衡配置中引用旧资源名,现需改为引用通过for_each创建的google_cloud_run_service.cr:
resource "google_compute_region_network_endpoint_group" "backendneg" { for_each = toset( ["domain1", "domain2"] ) name = "backendneg-${each.key}" project = "my_project" network_endpoint_type = "SERVERLESS" region = "${var.cr_location[0]}.${each.key}" # 同location变量问题 cloud_run { service = google_cloud_run_service.cr_domain1.name # 需修改引用 } }
解决方案
1. 修复域名特定值的变量映射问题
你的变量类型设计不合理,应使用**映射(map)**替代列表嵌套对象,直接通过域名key取值:
修改变量定义
variable "cr_locations" { type = map(string) description = "域名到Cloud Run部署区域的映射" default = { domain1 = "europe-west6" domain2 = "europe-southwest1" } }
更新Cloud Run资源配置
resource "google_cloud_run_service" "cr" { # 直接用变量的keys作为for_each集合,确保每个域名都有对应location for_each = var.cr_locations name = "cr-${each.key}" # 通过each.value直接获取对应域名的location location = each.value project = "my_project" template { # 原配置内容 ... } }
后续新增域名只需在var.cr_locations中添加键值对即可,无需修改其他代码,适配批量部署需求。
2. 修复for_each资源的引用问题
通过for_each创建的资源会成为映射类型的实例集合,需通过资源名[键名]的方式引用具体实例:
更新负载均衡NEG资源配置
resource "google_compute_region_network_endpoint_group" "backendneg" { # 复用cr_locations的keys,保持与Cloud Run资源的一致性 for_each = var.cr_locations name = "backendneg-${each.key}" project = "my_project" network_endpoint_type = "SERVERLESS" # 直接用each.value获取对应区域 region = each.value cloud_run { # 通过each.key引用对应域名的Cloud Run服务实例 service = google_cloud_run_service.cr[each.key].name } }
内容的提问来源于stack exchange,提问作者rimed
相关产品推荐
相关产品推荐

