嵌套列表中的 Terraform 嵌套循环

Terraform nested loop in nested list

我正在尝试创建一个动态方法来在最终用户将配置的多个环境中创建虚拟机。 尝试使用嵌套循环进行循环。扁平化功能、计数等,但还没有找到实现我的目标的方法。 我有 terrafrom.tfvars 结构如下:

Bigip_devices = {
    main_hub = {
      region             = "eastus"
      azs                = ["1"]            #Azure availabilty zones
      vnet_name               = "vnet-main"   # Vnet name to deploy to
      bigip_instance_count = 2            # Number of instnaces to delpoy
      cluster             = "yes"         # Deploy as a cluster or stand alone device
      version             = ""            # Leave blank for default value
      sku                 = ""            # Leave blank for default value - f5-bigip-virtual-edition-25m-best-hourly
      offer               = ""            # Leave blank for default value - f5-big-ip-best
      instance_type       = ""            # Leave blank for default value - Standard_DS3_v2
      disable_password_authentication = ""     #Leave blank for default value
      tags                = ""
    }
    spoke = {
      region             = "eastus"
      azs                = ["1","2"]            #Azure availabilty zones
      vnet_name               = "vnet-spoke"   # Vnet name to deploy to
      bigip_instance_count = 4            # Number of instnaces to delpoy
      cluster             = "yes"         # Deploy as a cluster or stand alone device
      version             = ""            # Leave blank for default value
      sku                 = ""            # Leave blank for default value - f5-bigip-virtual-edition-25m-best-hourly
      offer               = ""            # Leave blank for default value - f5-big-ip-best
      instance_type       = ""            # Leave blank for default value - Standard_DS3_v2
      disable_password_authentication = ""     #Leave blank for default value
      tags                = ""
    }
  }

迭代列表中每个键的正确方法是什么(在示例中有 2 个键 - 主中心和分支)并创建对应于 [=18 的虚拟机数量=]设置。 在上面的示例中,我想创建 2 个环境,一个有 2 个设备,第二个有 4 个设备。 有办法实现吗?

如果您将上面的复杂 JSON 转换为一个集合,该集合对您要创建的每个资源都有一个元素,那将非常方便。为此,您可以使用 flatten 函数。

locals {
  # A list of objects with one object per instance.
  flattened_values = flatten([
    for ip_key, ip in var.Bigip_devices : [
      for index in range(ip.bigip_instance_count) : {
        region  = ip.region
        azs            = ip.azs
        ip_index      = index
        ip_key        = ip_key
        cluster         = ip.cluster
        version        = ip.version
        sku   = ip.sku
        offer = ip.offer
        instance_type = ip.instance_type
        disable_password_authentication = ip.disable_password_authentication
        tags = ip.tags
      }
    ]
  ])
}

使用上面的flattened函数,你会得到下面的资源集合列表,你想创建。

flattened_value_output = [
  {
    "azs" = [
      "1",
    ]
    "cluster" = "yes"
    "disable_password_authentication" = ""
    "instance_type" = ""
    "ip_index" = 0
    "ip_key" = "main_hub"
    "offer" = ""
    "region" = "eastus"
    "sku" = ""
    "tags" = ""
    "version" = ""
  },
  {
    "azs" = [
      "1",
    ]
    "cluster" = "yes"
    "disable_password_authentication" = ""
    "instance_type" = ""
    "ip_index" = 1
    "ip_key" = "main_hub"
    "offer" = ""
    "region" = "eastus"
    "sku" = ""
    "tags" = ""
    "version" = ""
  },
  {
    "azs" = [
      "1",
      "2",
    ]
    "cluster" = "yes"
    "disable_password_authentication" = ""
    "instance_type" = ""
    "ip_index" = 0
    "ip_key" = "spoke"
    "offer" = ""
    "region" = "eastus"
    "sku" = ""
    "tags" = ""
    "version" = ""
  },
  {
    "azs" = [
      "1",
      "2",
    ]
    "cluster" = "yes"
    "disable_password_authentication" = ""
    "instance_type" = ""
    "ip_index" = 1
    "ip_key" = "spoke"
    "offer" = ""
    "region" = "eastus"
    "sku" = ""
    "tags" = ""
    "version" = ""
  },
  {
    "azs" = [
      "1",
      "2",
    ]
    "cluster" = "yes"
    "disable_password_authentication" = ""
    "instance_type" = ""
    "ip_index" = 2
    "ip_key" = "spoke"
    "offer" = ""
    "region" = "eastus"
    "sku" = ""
    "tags" = ""
    "version" = ""
  },
  {
    "azs" = [
      "1",
      "2",
    ]
    "cluster" = "yes"
    "disable_password_authentication" = ""
    "instance_type" = ""
    "ip_index" = 3
    "ip_key" = "spoke"
    "offer" = ""
    "region" = "eastus"
    "sku" = ""
    "tags" = ""
    "version" = ""
  },
]

从上面的集合中,您可以使用如下所示的唯一键迭代和创建资源::

resource "some_resource" "example" {
  for_each = {
    # Generate a unique string identifier for each instance
    for ip in local.flattened_value_output : format("%s-%02d", ip.ip_key, ip.ip_index + 1) => ip
  }
}

这样一来,资源的创建或更新就得到了保证,因为每个资源都使用唯一的密钥。

更多详情,请参考this discussion我与Hashicorp人员的交流。