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

如何通过variables.tf和terraform.tfvars配置Terraform循环并修复类型错误?

问题根源与解决方案

错误原因

变量定义中frontend_name和origin_host_name被声明为list(string)类型,但你在terraform.tfvars中直接赋值了单个字符串,而非符合要求的字符串列表,导致类型校验失败。


解决方案(二选一,根据业务场景选择)

方案1:保持列表类型(适配多前端/多源场景)

如果你的业务需要每个源组对应多个前端名称或源主机名,修改terraform.tfvars,将单个字符串用方括号包裹为列表:

fd_appadmin = {
  appadmin = {
    frontend_name     = ["dev-appadmin-web"]
    origin_host_name  = ["appadmin-dev-eastus"]
  }
  appadminv2 = {
    frontend_name     = ["admin-portalv2"]
    origin_host_name  = ["appadmin2-dev-eastus"]
  }
}

方案2:修改变量为单字符串类型(适配单前端/单源场景)

若每个源组仅对应一个前端和一个源,更合理的做法是调整变量定义,将list(string)改为string,无需修改terraform.tfvars:

# variables.tf
variable "fd_appadmin" {
  type = map(object({
    frontend_name     = string
    origin_host_name  = string
  }))
}

完整多组件配置示例

结合你的需求,以下是包含源组、源、路由规则的完整main.tf配置,通过for_each实现批量创建:

# Front Door Profile(已存在的基础资源)
resource "azurerm_cdn_frontdoor_profile" "appfd" {
  name                = "appfd-profile"
  resource_group_name = azurerm_resource_group.example.name
  sku_name            = "Premium_AzureFrontDoor"
}

# Front Door Endpoint(需提前创建)
resource "azurerm_cdn_frontdoor_endpoint" "appfd_endpoint" {
  name                     = "appfd-endpoint"
  cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.appfd.id
}

# 源组资源
resource "azurerm_cdn_frontdoor_origin_group" "appadmin_group" {
  for_each                    = var.fd_appadmin
  name                        = each.key
  cdn_frontdoor_profile_id    = azurerm_cdn_frontdoor_profile.appfd.id
  session_affinity_enabled    = true
}

# 源资源(每个源组对应一个源)
resource "azurerm_cdn_frontdoor_origin" "appadmin_origin" {
  for_each                    = var.fd_appadmin
  name                        = "${each.key}-origin"
  cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.appadmin_group[each.key].id
  host_name                   = each.value.origin_host_name
  http_port                   = 80
  https_port                  = 443
}

# 路由规则资源
resource "azurerm_cdn_frontdoor_route" "appadmin_route" {
  for_each                    = var.fd_appadmin
  name                        = "${each.key}-route"
  cdn_frontdoor_endpoint_id   = azurerm_cdn_frontdoor_endpoint.appfd_endpoint.id
  cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.appadmin_group[each.key].id
  patterns_to_match           = ["/*"]
  forwarding_protocol         = "HttpsOnly"
  # 若用方案1(列表类型)直接用each.value.frontend_name;方案2则转成列表:[each.value.frontend_name]
  frontend_endpoints          = [each.value.frontend_name]
}

环境隔离实现

通过创建不同环境的tfvars文件(如dev.tfvars、qa.tfvars、prod.tfvars),分别配置对应环境的源组、源信息,执行时指定对应文件即可:

# 开发环境
terraform plan -var-file=dev.tfvars
terraform apply -var-file=dev.tfvars

# 生产环境
terraform plan -var-file=prod.tfvars
terraform apply -var-file=prod.tfvars

内容的提问来源于stack exchange,提问作者Patrick Lane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 05:14:57