Terraform - 将列表列表转换为新的列表列表

Terraform - transform list of lists to into a new list of lists

在 Terraform 中,我需要转换我的输入数据结构,例如:

vip_lists = [
    ["1.0.1.1", "1.0.1.2", "1.0.1.3", "1.0.1.4"]
    ["1.0.2.1", "1.0.2.2", "1.0.2.3", "1.0.2.4"]
    ["1.0.0.1", "1.0.0.2", "1.0.0.3", "1.0.0.4"]
]

产生这样的输出:

vip_sets = [
    ["1.0.1.1", "1.0.2.1", "1.0.0.1"]
    ["1.0.1.2", "1.0.2.2", "1.0.0.2"]
    ["1.0.1.3", "1.0.2.3", "1.0.0.3"]
    ["1.0.1.4", "1.0.2.4", "1.0.0.4"]
]

所以基本上,我需要获取我的输入列表列表并创建一个输出,它也是一个列表列表,但其第 0 个列表是输入中每个列表中的第 0 个元素的列表...然后对于 1st 再次相同,依此类推。 我无法提前知道输入中有多少列表或它们有多长,但如果有帮助,我们可以假设所有列表的长度都相同。

我几乎尝试了所有我能想到的方法并在网上进行了搜索,但一直没有成功。非常欢迎所有建议!

这有点可怕,但它有效(虽然我没有测试如果 vip_lists 为空它会做什么。可能会崩溃,因为我正在索引 vip_lists[0] 没有检查):

locals {
  vip_lists = [
    ["1.0.1.1", "1.0.1.2", "1.0.1.3", "1.0.1.4"],
    ["1.0.2.1", "1.0.2.2", "1.0.2.3", "1.0.2.4"],
    ["1.0.0.1", "1.0.0.2", "1.0.0.3", "1.0.0.4"]
  ]

  vip_sets = [for i in range(0, length(local.vip_lists[0])): [for j in range(0, length(local.vip_lists)): local.vip_lists[j][i]]]
}

output "vip_sets" {
  value = local.vip_sets
}
$ terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

vip_sets = [
  [
    "1.0.1.1",
    "1.0.2.1",
    "1.0.0.1",
  ],
  [
    "1.0.1.2",
    "1.0.2.2",
    "1.0.0.2",
  ],
  [
    "1.0.1.3",
    "1.0.2.3",
    "1.0.0.3",
  ],
  [
    "1.0.1.4",
    "1.0.2.4",
    "1.0.0.4",
  ],
]

我曾经为 github.com/mineiros-io 上的一个模块的长度不相同的列表列表编写过此版本,我们使用此类转换使用 count 创建二维资源集. (这些未在 atm 中使用,因为我们将它们转换为地图以供资源级别 for_each 使用)。

locals {
  matrix = [
    ["1.0.1.1", "1.0.1.4"],
    ["1.0.2.1", "1.0.2.2", "1.0.2.3", "1.0.2.4"],
    ["1.0.0.1", "1.0.0.3", "1.0.0.4"]
  ]

  row_lengths = [
    for row in local.matrix : length(row)
  ]

  max_row_length = max(0, local.row_lengths...)

  output = [
    for i in range(0, local.max_row_length) : [
      for j, _ in local.matrix : try(local.matrix[j][i], null)
    ]
  ]

  output_compact = [
    for i in range(0, local.max_row_length) : compact([
      for j, _ in local.matrix : try(local.matrix[j][i], null)
    ])
  ]
}

output "matrix" {
  value = local.output
}

output "compact" {
  value = local.output_compact
}

可以处理动态列表大小并输出它们紧凑或填充 null 值:

Outputs:

compact = [
  [ "1.0.1.1", "1.0.2.1", "1.0.0.1" ],
  [ "1.0.1.4", "1.0.2.2", "1.0.0.3" ],
  [ "1.0.2.3", "1.0.0.4" ],
  [ "1.0.2.4" ],
]

matrix = [
  [ "1.0.1.1", "1.0.2.1", "1.0.0.1" ],
  [ "1.0.1.4", "1.0.2.2", "1.0.0.3" ],
  [ null,      "1.0.2.3", "1.0.0.4" ],
  [ null,      "1.0.2.4", null      ],
]

我知道一个答案已经被接受,但也许有人仍然可以使用这个动态版本。