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

Terraform如何扁平化嵌套在对象列表中的DNS记录列表?

Terraform DNS记录结构化提取问题解决

我正在配置DNS区域及其中的记录,但没法把现有DNS对象列表转换成Terraform配置需要的结构化集合。每个DNS对象包含多种记录列表(A、CNAME、MX、TXT等),我需要把每种类型的记录单独提取成列表,方便后续用count = length(locals.a_records)这类方式创建资源。尝试用merge和flatten但始终不对,还一直报这些错误:

  • Error: Invalid 'for' expression. Extra characters after the end of the 'for' expression.
  • Error: Missing attribute value. Expected an attribute value, introduced by an equals sign ("=").
  • Error: Invalid 'for' expression. Key expression is required when building an object.
  • Error: Missing key/value separator. Expected an equals sign ("=") to mark the beginning of the attribute value.

现有变量定义

variable "dns_target_child_zones" {
  type = list(object({
    name      = string
    a_records = list(object({
      name        = string
      ttl         = number
      ip_address  = string
    }))
    cname_records = list(object({
      name        = string
      ttl         = number
      record      = string
    }))
    mx_records = list(object({
      name        = string
      ttl         = number
      record      = list(object({
        preference  = number
        exchange    = string
      }))
    }))
    txt_records = list(object({
      name        = string
      ttl         = number
      record      = list(object({
        value  = string
      }))
    }))
  }))
}

本地变量模板

locals {
  a_records = flatten ([

  ])
  cname_records = flatten ([

  ])
  mx_records = flatten ([

  ])
  txt_records = flatten ([

  ])        
}

期望输出结构

[
 {
   name                = 
   zone_name           = 
   ttl                 = 
   records             = 
 },
 {
   name                = 
   zone_name           = 
   ttl                 = 
   records             = 
 }
 ...
]

正确的本地变量配置

针对每种记录类型,用嵌套for循环遍历区域和记录,再通过flatten把嵌套列表转成一维列表,完全匹配你要的结构:

locals {
  # A记录提取
  a_records = flatten([
    for zone in var.dns_target_child_zones : [
      for a in zone.a_records : {
        name       = a.name
        zone_name  = zone.name
        ttl        = a.ttl
        records    = [a.ip_address] # 转成列表格式匹配通用结构
      }
    ]
  ])

  # CNAME记录提取
  cname_records = flatten([
    for zone in var.dns_target_child_zones : [
      for cname in zone.cname_records : {
        name       = cname.name
        zone_name  = zone.name
        ttl        = cname.ttl
        records    = [cname.record]
      }
    ]
  ])

  # MX记录提取 - 按DNS标准格式拼接优先级与邮件服务器
  mx_records = flatten([
    for zone in var.dns_target_child_zones : [
      for mx in zone.mx_records : {
        name       = mx.name
        zone_name  = zone.name
        ttl        = mx.ttl
        records    = [for m in mx.record : "${m.preference} ${m.exchange}"]
      }
    ]
  ])

  # TXT记录提取 - 直接提取value列表
  txt_records = flatten([
    for zone in var.dns_target_child_zones : [
      for txt in zone.txt_records : {
        name       = txt.name
        zone_name  = zone.name
        ttl        = txt.ttl
        records    = [for t in txt.record : t.value]
      }
    ]
  ])
}

关键说明

  1. 嵌套for循环先遍历每个DNS区域,再遍历区域内的对应类型记录,确保每条记录都关联所属区域
  2. flatten将双层嵌套列表(区域→记录)转换为一维列表,满足Terraform count参数的使用要求
  3. 所有记录的records字段统一使用列表格式,保持结构一致性,适配大多数DNS资源的参数要求
  4. MX记录按DNS标准格式拼接成"优先级 邮件服务器"字符串,符合主流DNS服务商的配置规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 21:18:33