Terraform如何遍历Map变量内列表生成Datadog合成测试资源?
解决Terraform生成多DNS IP Datadog Synthetic测试的问题
你的核心问题是for_each的取值为列表而非单个元素,导致Terraform无法为每个DNS IP创建独立资源。需要通过flatten函数将服务器与IP的组合扁平化,生成唯一键值对来遍历。
正确实现代码
resource "datadog_synthetics_test" "dns_test" { # 扁平化服务器与DNS IP的组合,生成唯一标识的键 for_each = { for idx, test_item in flatten([ for server_name, server_info in var.dns : [ for dns_ip in server_info.dns_ips : { server_name = server_name hostname = server_info.hostname dns_ip = dns_ip } ] ]) : "${test_item.server_name}-${test_item.dns_ip}" => test_item } name = "${var.synthetic_prefix} ${each.value.hostname} - Resolve @${each.value.dns_ip}" request_definition { dns_server = each.value.dns_ip dns_server_port = 0 host = var.dns_domain_name[0] no_saving_response_body = false number_of_packets = 0 port = 0 should_track_hops = false timeout = 0 } # 补充Datadog Synthetic测试必填字段(根据实际需求调整) type = "dns" status = "live" locations = ["aws:us-east-1"] }
代码说明
扁平化逻辑:
- 外层遍历
var.dns的每个服务器,内层遍历对应服务器的dns_ips列表,将每个IP与服务器信息组合成独立对象 - 用
flatten将嵌套列表展开为一维列表,每个元素对应一个「服务器-IP」组合 - 最后将列表转为map,用
${server_name}-${dns_ip}作为唯一键,确保每个资源实例的唯一性
- 外层遍历
资源字段修正:
- 直接用
each.value.dns_ip引用当前遍历的IP地址 - 名称中使用
each.value.hostname匹配你需求中的服务器标识
- 直接用
额外注意
你的var.dns变量存在字段不匹配问题,类型定义与默认值的字段名不一致,会导致Terraform报错,需修正:
variable "dns" { type = map(object({ name = string hostname = string dns_ips = list(string) })) default = { "server1" = { name = "Server One" # 修正为type定义的name字段 hostname = "vm-01" dns_ips = ["128.0.0.8", "128.0.0.9", "128.0.0.10"] } "server2" = { name = "Server Two" # 修正为type定义的name字段 hostname = "vm-02" # 修正为type定义的hostname字段,同时区分服务器 dns_ips = ["129.0.0.8", "129.0.0.9", "129.0.0.10", "129.0.0.11"] } } }
内容的提问来源于stack exchange,提问作者cloud110
相关产品推荐
相关产品推荐

