从地图列表中创建重组后的地图

时间:2020-07-15 20:31:34

标签: terraform

我遇到了几天无法解决的问题。我有一个定义数据磁盘的数据结构,其中包括每个磁盘的映射列表:

variable "data_disks_node" {
  description = "Data disk configuration lun, size in gib, mountpoint"
  default = [
    {
      lun = 0
      size = 200
      mount = "/opt/mount1"
    },
    {
      lun = 1
      size = 32
      mount = "/opt/mount2"
    },
  ]
}

我正在使用这种结构通过动态块和for_each创建数据磁盘(效果很好),但需要创建一个标签映射,并使用来自相同数据结构的值。

我需要使用已配置的数据磁盘和挂载点标记创建的资源(不要问,不能更改该要求),并且需要以下映射结果:

data_disk_tags = {
  lun0 = "/opt/mount1"
  lun1 = "/opt/mount2"
}

因此,我不仅需要从地图列表中创建地图,而且还需要过滤结果,将一个值映射为键,将另一个值映射为值,还需要在新键之前添加字符串“ lun” 。我为此不知所措,因为我只在Terraform那里工作过,无法找到解决该问题的任何有案可查的案例。如果重要,则使用的Terraform为0.12.20。到目前为止,我最接近(甚至没有接近)的是:

locals {
  vm_joined_tags = merge(var.vm_tags, zipmap(flatten([for item in var.vm_data_disk_configuration : keys(item)]), flatten([for item in var.vm_data_disk_configuration : values(item)])))
}

可以工作,但仅创建第一个来源地图和键值之类的地图

{
  lun = 1
  size = 200
  mount = "/opt/mount1"
}

,甚至没有第二张地图。我非常感谢您提供的任何帮助或建议。可以更改数据结构,但应避免,因为其他模块代码依赖于此。如果需要任何其他输入,请告诉我,我会提供。

1 个答案:

答案 0 :(得分:2)

您看起来似乎在尝试遍历列表的正确路径,但是有一种更简单的方法来获得该列表:

variable "data_disks_node" {
  description = "Data disk configuration lun, size in gib, mountpoint"
  default = [
    {
      lun   = 0
      size  = 200
      mount = "/opt/mount1"
    },
    {
      lun   = 1
      size  = 32
      mount = "/opt/mount2"
    },
  ]
}

locals {
  vm_joined_tags = { for disk in var.data_disks_node : format("lun%s", disk.lun) => disk.mount }
}

output "vm_joined_tags" {
  value = local.vm_joined_tags
}

应用此命令将输出您所需的结构:

Outputs:

vm_joined_tags = {
  "lun0" = "/opt/mount1"
  "lun1" = "/opt/mount2"
}

for expression上加上花括号意味着它会创建一个地图(它与Python's dictionary comprehensions具有相似的语法):

for表达式中括号的类型决定什么类型的 结果产生。上面的示例使用[],它们会产生一个 元组。如果改用{},则结果是一个对象,另外两个 结果表达式必须以=>符号隔开:

{for s in var.list : s => upper(s)}

因此,以上示例在var.data_disks_node中的磁盘上循环,并创建了一个映射,该映射的键包含每个磁盘的lun,并以字符串"lun"为前缀,并带有每个磁盘中的mount