在地形表单中合并列表中的地图



我有一个这样的地图列表 -

[
  {
    "outer_key_1" = [
      {
        "ip_cidr" = "172.16.6.0/24"
        "range_name" = "range1"
      },
      {
        "ip_cidr" = "172.16.7.0/24"
        "range_name" = "range2"
      },
      {
        "ip_cidr" = "172.17.6.0/24"
        "range_name" = "range3"
      },
      {
        "ip_cidr" = "172.17.7.0/24"
        "range_name" = "range4"
      },
    ]
  },
  {
    "outer_key_2" = [
      {
        "ip_cidr" = "172.16.5.0/24"
        "range_name" = "range5"
      },
      {
        "ip_cidr" = "172.17.5.0/24"
        "range_name" = "range6"
      },
    ]
  },
]

我想合并列表中的地图。这是在输出变量module.module_name.module_op中。

所需输出:


{
    "outer_key_1" = [
      {
        "ip_cidr" = "172.16.6.0/24"
        "range_name" = "range1"
      },
      {
        "ip_cidr" = "172.16.7.0/24"
        "range_name" = "range2"
      },
      {
        "ip_cidr" = "172.17.6.0/24"
        "range_name" = "range3"
      },
      {
        "ip_cidr" = "172.17.7.0/24"
        "range_name" = "range4"
      },
    ]
    "outer_key_2" = [
      {
        "ip_cidr" = "172.16.5.0/24"
        "range_name" = "range5"
      },
      {
        "ip_cidr" = "172.17.5.0/24"
        "range_name" = "range6"
      },
    ]
}

我已经使用

locals {
  result = merge(module.module_name.module_op[0], module.module_name.module_op[1])
}

我如何以更迭代的方式执行此操作。

我不会总是在我的列表中只有 2 张地图,它可以更多。

我尝试在地形形式 12 中使用 for 循环,如下所示 -

output "result" {
  value = [ for tuple in module.module_name.module_op : merge(tuple) ]
}

而这个——

output "secondary_subnets" {
  value = { for tuple in module.module_name.module_op : merge(tuple) }
}

第一个给我输入,第二个给我一个错误,说我需要添加一个键,因为我正在返回一个对象。

有没有办法做到这一点?

提前谢谢。

您实际上可以将映射列表传递给 merge() 函数:

Terraform 语言具有将列表/元组转换为多个参数的一般功能,方法是在最后一个参数表达式之后使用特殊符号...

因此,在上面的示例中,您可以执行以下操作:

locals {
  result = merge(module.module_name.module_op...)
}

然后,这将合并列表中的所有地图,从而允许动态调整列表大小。

不幸的是,您的地图values()是列表。否则,您可以执行以下操作,这将适用于list(map(<not_list>))

例如

locals {
  my_list_of_maps = [
    {
       key1 = "val1"
       key2 = "val2"
    },
    {
       key3 = "val3"
    },
  ]
}
zipmap(
  flatten(
    [for item in local.my_list_of_maps : keys(item)]
  ),
  flatten(
    [for item in local.my_list_of_maps : values(item)]
  )
)

这将像这样处理

zipmap(
  flatten([["key1", "key2"], ["key3"]]),
  flatten([["val1", "val2"], ["val3"]])
)

=>

zipmap(
  ["key1", "key2", "key3"],
  ["val1", "val2", "val3"]
)

=>

{
  key1 = "val1"
  key2 = "val2"
  key3 = "val3"
}

我在这里使用了一个简单的list(map(string)),但地图的values()可能更复杂。 但是,由于使用了flatten()(以递归方式平展嵌套列表(,因此values()本身不能是列表。

为了使其正常工作,您可以随时将数据转换为如下所示:

[
  {
    "outer_key_1" = {
      range1 = "172.16.6.0/24"
      range2 = "172.16.7.0/24"
      range3 = "172.17.6.0/24"
      range4 = "172.17.7.0/24"
    }
  },
  {
    "outer_key_2" = {
      range5 = "172.16.5.0/24"
      range6 = "172.17.5.0/24"
    }
  },
]

上述逻辑将毫无问题地工作。

顺便说一句,zipmap()的行为就像一个merge(). 因此,如果有重复的密钥,迟到的将覆盖现有密钥。

最新更新