【问题标题】:Terraform nested loop in nested list嵌套列表中的 Terraform 嵌套循环
【发布时间】:2021-01-27 03:17:05
【问题描述】:

我正在尝试创建一种动态方法来在最终用户配置的多个环境中创建虚拟机。 尝试使用嵌套循环进行循环。扁平化功能、计数等,但还没有找到实现目标的方法。 我有具有以下结构的 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 个键 - 主集线器和辐条)并创建与 bigip_instance_count 设置对应的虚拟机数量的正确方法是什么。 在上面的示例中,我想创建 2 个环境,一个有 2 个设备,第二个有 4 个设备。 有没有办法实现?

【问题讨论】:

    标签: terraform terraform-provider-azure terraform0.12+


    【解决方案1】:

    如果您将上述复杂的 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
      }
    }
    

    这样可以保证资源的创建或更新,因为每个资源都使用唯一的密钥。

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

    【讨论】:

    • 很棒的解决方案!谢谢,就像一个魅力。例子和解释也很棒。
    猜你喜欢
    • 1970-01-01
    • 2021-07-08
    • 2020-12-03
    • 2018-01-06
    • 2019-09-26
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多