Terraform中用for_each遍历双Map创建Azure SRV记录的问题
解决方案
一、修正dynamic块内的迭代问题
Terraform的dynamic块拥有独立的迭代器变量,默认名称为块本身的名称(此处为record),而非外部资源的each。你当前代码中使用的each.key会指向外部azurerm_dns_srv_record资源级别的for_each键值,而非var.targets的元素。需根据var.targets的结构调整:
情况1:var.targets为列表类型
若var.targets是类似["target1.example.com", "target2.example.com"]的列表,需先转为集合(for_each要求可哈希类型),再通过record.value获取目标值:
resource "azurerm_dns_srv_record" "srv_dns_record" { for_each = { for key, value in var.clusters : key => value if some condition } name = "your-srv-record-name" # 替换为实际SRV记录名称 zone_name = azurerm_dns_zone.cluster_dns_zone[each.key].name resource_group_name = azurerm_resource_group.main.name ttl = 60 dynamic "record" { for_each = toset(var.targets) content { priority = 1 weight = 5 port = 443 target = record.value } } }
情况2:var.targets为映射类型
若var.targets是包含自定义属性的映射(如{"target1" = {priority=1, weight=5}, "target2" = {priority=2, weight=10}}),可直接遍历并通过record.key/record.value访问对应属性:
resource "azurerm_dns_srv_record" "srv_dns_record" { for_each = { for key, value in var.clusters : key => value if some condition } name = "your-srv-record-name" zone_name = azurerm_dns_zone.cluster_dns_zone[each.key].name resource_group_name = azurerm_resource_group.main.name ttl = 60 dynamic "record" { for_each = var.targets content { priority = record.value.priority weight = record.value.weight port = 443 target = record.key } } }
二、无需循环的实现方式
仅当SRV记录的目标数量固定且少量时,可手动定义多个record块,完全避免循环:
resource "azurerm_dns_srv_record" "srv_dns_record" { for_each = { for key, value in var.clusters : key => value if some condition } name = "your-srv-record-name" zone_name = azurerm_dns_zone.cluster_dns_zone[each.key].name resource_group_name = azurerm_resource_group.main.name ttl = 60 # 手动添加多个record块 record { priority = 1 weight = 5 port = 443 target = "target1.example.com" } record { priority = 1 weight = 5 port = 443 target = "target2.example.com" } }
但如果目标数量是动态生成的(比如从变量、其他资源输出获取),必须使用dynamic块——因为Terraform不支持在嵌套块上使用count参数,dynamic是官方提供的唯一批量生成嵌套块的方式。
内容的提问来源于stack exchange,提问作者Ajith Selvan
相关产品推荐
相关产品推荐

