首页 > 解决方案 > Terraform 动态循环列表中的元素并根据值扩展

问题描述

这有点难以描述。因此,为了清楚起见,我简化了它后,有一张看起来像这样的地图:

server_ip_configs = {
mgmt        = {
    ct      = "1"
    }
applicationgateway    = {
    ct      = "1"
    }
monitor     = {
    ct      = "1"
    }
app      = {
    ct      = "3"
    }
}

我想要做的是遍历地图以创建一个平面列表,其中元素乘以 ct 属性的数量到一个新的平面列表中。所以我们最终得到一个看起来有点像这样的列表:

server_ip_configs_mapped = [
       {
        name      = "mgmt-1"
        }
       {
        name      = "applicationgateway-1"
        }
       {
        name      = "monitor-1"
        }
       {
        name      = "app-1"
        }
       {
        name      = "app-2"
        }
       {
        name      = "app-3"
        }

    ]

通过设置变量为每一行显式创建元素列表是微不足道的:

data "null_data_source" "server_list_ip_configs" {
  count = lookup(var.server_ip_configs[var.server_role], "ct", 0)

  inputs = {
    name    =   "${var.server_role}-${count.index +1}"
  }
}

我可以将它放在一个模块中并调用该模块的多个实例并连接结果。但这不是一个很好的方法,而且一点也不干。我是否认为在 Terraform 中没有其他方法可以做到这一点?是因为 terraform 本质上是声明性的,也许我应该声明一个包含多个实例的列表,而不是尝试生成一个?使用 for 循环将不起作用,因为您不能使用整数从我所看到的内容中显式地迭代。所以不行:

for i in 5 

对此欢迎任何答案。谢谢。

标签: terraform

解决方案


@Helder 接近了,但我对请求的解释略有不同。您的意图是根据 ct 值构建列表,这看起来像一个计数。这应该是您正在寻找的。请注意使用range()来执行您正在查看的for i in 5语句。

variable "server_ip_configs" {
  default = {
    mgmt               = { ct = "1" }
    applicationgateway = { ct = "1" }
    monitor            = { ct = "1" }
    app                = { ct = "3" }
  }
}

locals {
  server_ip_configs_mapped = flatten([
    for server, count in var.server_ip_configs : [
      for i in range(count.ct) : {
        "name" = join("-", [server, i+1])
      }
    ]
  ])
}

output server_ip_configs_mapped { value = local.server_ip_configs_mapped }

输出:

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

Outputs:

server_ip_configs_mapped = [
  {
    "name" = "app-1"
  },
  {
    "name" = "app-2"
  },
  {
    "name" = "app-3"
  },
  {
    "name" = "applicationgateway-1"
  },
  {
    "name" = "mgmt-1"
  },
  {
    "name" = "monitor-1"
  },
]

推荐阅读