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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:45:37