You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:42:28