当重复的键应该引发​​错误时,terraform `map` 替代方案

ams*_*ms1 3 dictionary key duplicates terraform

鉴于:

正如https://github.com/hashicorp/terraform/issues/28727中所述,如果我们在地图中有重复的键,我们不会收到错误:

下面引用来自github问题

locals {
  local_dbs = {
    db1 = { a = "1a" }
    db1 = { a = "2a" }    // notice the key here is the same as the previous (e.g. a mistake)
    db3 = { a = "3a" }
  }
}

output locals_map_out {
  value = local.local_dbs
}
Run Code Online (Sandbox Code Playgroud)

上面产生了这些输出

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

locals_map_out = {
  "db1" = {
    "a" = "2a"
  }
  "db3" = {
    "a" = "3a"
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意第一个 db1 映射条目丢失了。没有错误,也没有警告。它只是默默地用第二个地图条目替换了第一个地图条目。

github问题引用结束

我的问题是:

什么是一个好的(外观相似,优雅,几行代码)替代使用map会引发重复“键”错误的情况?

前任。地图列表+验证码?

locals {
  local_dbs = [
    {db1 = { a = "1a" }},
    {db1 = { a = "2a" }},   // notice the key here is the same as the previous (e.g. a mistake)
    {db3 = { a = "3a" }},
  ]

  // code that raises error?
}

output locals_map_out {
  value = local.local_dbs
}
Run Code Online (Sandbox Code Playgroud)

谢谢。

Mar*_*cin 6

TF 中没有自定义错误或异常,但检查重复项的一种方法是获取唯一键的列表,然后尝试访问最后一个元素。如果所有键确实是唯一的,则操作将会成功。如果没有,就会出错:

locals {
  local_dbs = [
    {db1 = { a = "1a" }},
    {db1 = { a = "2a" }},   // notice the key here is the same as the previous (e.g. a mistake)
    {db3 = { a = "3a" }},
  ]

  check_duplicatates = distinct([for v in local.local_dbs: keys(v)])[length(local.local_dbs)-1]
}

Run Code Online (Sandbox Code Playgroud)

更新

正如output@MarkoE 所建议的:

output "check_duplicatates" {
  value = local.local_dbs
  #sensitive = true
  precondition {
    condition     = length(distinct([for v in local.local_dbs: keys(v)])) == length(local.local_dbs)
    error_message = "Keys in local.local_dbs are NOT unique."
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果输出中需要它,也许它也可以与“前提条件”一起使用。 (3认同)