如何用for_each遍历多层变量映射并访问嵌套配置?
解决Terraform遍历多层映射与嵌套块的问题
一、Web App嵌套配置的访问
你遇到的each.value.site_config.health_check_path无法生效,大概率是变量类型未正确定义导致Terraform无法识别嵌套属性。正确的做法是先在variables.tf中明确application_services的结构,再在资源中正常访问嵌套属性:
1. 完善变量定义(variables.tf)
variable "application_services" { type = map(object({ name = string location = string resource_group = string site_config = object({ health_check_path = string health_check_eviction_time_in_min = string }) })) }
2. 正确引用嵌套属性(main.tf)
resource "azure_windows_web_app" "windows_web_app" { for_each = var.application_services name = each.value.name location = each.value.location resource_group = each.value.resource_group site_config { health_check_path = each.value.site_config.health_check_path health_check_eviction_time_in_min = each.value.site_config.health_check_eviction_time_in_min } }
这样就能正常读取site_config下的嵌套属性,for_each遍历顶层映射时,完全可以访问其内部的嵌套结构。
二、Application Gateway多同类型块的处理
你示例中重复使用backend_https_settings作为键的写法是错误的——Map中不允许重复键,后定义的会覆盖前一个。要实现多个同类型块,需要将同类型配置组织为带唯一标识的Map或List,再用Terraform的dynamic块遍历生成对应资源块。
1. 修正变量结构(vars.tfvars)
将重复的backend_https_settings改为一个Map,用唯一名称作为键:
application_gateway = { gw01 = { name = "gateway01" location = "eastus" resource_group = "rg02" backend_https_settings = { http = { name = "http" path = "/" port = 80 protocol = "Http" request_timeout = 60 } https = { name = "https" path = "/" port = 443 protocol = "Https" request_timeout = 60 } } } gw02 = { # 其他网关配置... } }
2. 用dynamic块生成多嵌套块(main.tf)
针对azurerm_application_gateway中的backend_https_settings块,使用dynamic遍历每个配置项:
resource "azurerm_application_gateway" "gateway" { for_each = var.application_gateway name = each.value.name location = each.value.location resource_group_name = each.value.resource_group # 其他网关顶层配置... # 遍历生成多个backend_https_settings块 dynamic "backend_https_settings" { for_each = each.value.backend_https_settings content { name = backend_https_settings.value.name path = backend_https_settings.value.path port = backend_https_settings.value.port protocol = backend_https_settings.value.protocol request_timeout = backend_https_settings.value.request_timeout # 其他backend_https_settings所需属性... } } }
三、最佳实践
- 明确变量类型:始终在
variables.tf中定义清晰的类型结构,避免Terraform对嵌套属性的解析错误。 - 用唯一键组织多块配置:对于需要重复生成的资源块,将其组织为Map(而非重复键),确保每个配置项有唯一标识,便于维护和遍历。
- dynamic块的灵活使用:
dynamic是处理Terraform中多嵌套块的标准方式,支持遍历Map/List生成任意数量的同类型块。
内容的提问来源于stack exchange,提问作者TheWellington
相关产品推荐
相关产品推荐

