如何解决Terraform中Cisco DNA站点部署的重复对象键错误
解决Terraform创建Cisco DNA Center站点时的"Duplicate object key"错误
问题根源
当使用dnacenter_floor资源创建楼层时,若for_each仅以floor.name作为唯一键,不同建筑(如B01、B02)下的同名楼层(如F03)会导致键重复,触发"Duplicate object key"错误——因为Terraform要求for_each的键必须全局唯一。
解决方案:使用复合键确保唯一性
将建筑标识(名称或ID)与楼层名称组合作为for_each的键,这样即使楼层名称相同,只要所属建筑不同,键就不会重复。
步骤1:确认变量结构
确保variables.tf中定义的建筑与楼层层级结构正确,示例如下:
variable "buildings" { type = list(object({ name = string # 其他建筑属性(如地址、纬度等) floors = list(object({ name = string floor_number = number # 其他楼层属性(如描述、高度等) })) })) description = "List of buildings with their associated floors" }
步骤2:调整dnacenter_floor资源的for_each配置
场景1:直接引用变量中的建筑信息
如果建筑是通过变量定义(而非Terraform创建),可以直接用建筑名称+楼层名称生成复合键:
resource "dnacenter_floor" "site_floors" { # 用merge+嵌套循环生成唯一键:建筑名称-楼层名称 for_each = merge([ for building in var.buildings : { for floor in building.floors : "${building.name}-${floor.name}" => { building_name = building.name floor_name = floor.name floor_number = floor.floor_number # 其他楼层属性 } } ]...) # 资源必填参数配置 building_id = dnacenter_building.site_buildings[each.value.building_name].id name = each.value.floor_name floor_number = each.value.floor_number # 补充其他必填参数(如 height, rf_model 等) }
场景2:建筑由Terraform创建
如果建筑是通过dnacenter_building资源生成的,直接引用建筑资源的ID和名称:
# 先创建建筑 resource "dnacenter_building" "site_buildings" { for_each = { for bldg in var.buildings : bldg.name => bldg } name = each.value.name # 其他建筑必填参数 } # 再创建楼层,用建筑名称+楼层名称作为唯一键 resource "dnacenter_floor" "site_floors" { for_each = merge([ for bldg_name, bldg in dnacenter_building.site_buildings : { for floor in var.buildings[index(var.buildings, bldg)].floors : "${bldg_name}-${floor.name}" => { building_id = bldg.id floor_name = floor.name floor_number = floor.floor_number } } ]...) building_id = each.value.building_id name = each.value.floor_name floor_number = each.value.floor_number # 补充其他必填参数 }
原理说明
复合键${building.name}-${floor.name}保证了键的全局唯一性:比如B01-F03和B02-F03是两个完全不同的键,Terraform会将它们识别为独立的资源实例,从而避免重复键错误。
内容的提问来源于stack exchange,提问作者MupEHcEH
相关产品推荐
相关产品推荐

