如何通过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
相关产品推荐
相关产品推荐

