首页 > 解决方案 > Terraform:当传入的变量是地图列表的列表时,如何迭代资源组中的名称或另一个变量?

问题描述

这是我到目前为止所拥有的,虽然我可以使用局部变量提取特定列表或名称,但我无法将其转换到资源组中。首先,我是否以正确的方式尝试这样做?如果不是,我如何迭代子网的名称,以便添加属于相应 vnet 映射的子网?

variable "vnets" {
  default = [
    {
      vnet_name     = "test-vnet"
      address_space = "10.250.0.0"
      network_size  = 16
      subnets = [
        {
          name                     = "first-subnet"
          network_security_group   = "first-nsg"
          security_group_rules = [
            {
              name                       = "first-sg"
              priority                   = 100
            }
          ]
        },
        {
          name                     = "second-subnet"
          network_security_group   = "second-nsg"
          security_group_rules = [
            {
              name                       = "second-sg"
              priority                   = 100
            }
          ]
        }
      ]
    }
  ]
}


locals {
   
   subnet_names = { 
         for vnet in var.vnets[*]:
           (vnet.vnet_name) =>  vnet.subnets[*].name
   }
   
   security_group_names = flatten(var.vnets[*].subnets[*].security_group_rules[*].name)

}

resource "azurerm_subnet" "subnets" {
  count               = length(var.vnets)
  #??? name                      = locals.subnet_names[count.index].subnets.name
 
  
  resource_group_name       = data.azurerm_resource_group.network_group.name
  virtual_network_name      = azurerm_virtual_network.vnets.*.name
  address_prefixes     = ["10.0.1.0/24"]

}

标签: azureterraformterraform-provider-azure

解决方案


我认为最简单的方法是将你的subnet_names:

locals {
   
   subnet_names = { 
         for vnet in var.vnets[*]:
           (vnet.vnet_name) =>  vnet.subnets[*].name
   }
   
   security_group_names = flatten(var.vnets[*].subnets[*].security_group_rules[*].name)
   

   # uniqueness of "${vnet}-${subnet}" pairs is assumed. it will not work
   # if the pairs are not unique
   subnet_names_flat = merge([
         for vnet, subnets in local.subnet_names:
           {
             for subnet in subnets:          
               "${vnet}-${subnet}" => {name = vnet, subnet = subnet}
           }
         ]...)
     
}

这将导致subnet_names_flat

{
  "test-vnet-first-subnet" = {
    "name" = "test-vnet"
    "subnet" = "first-subnet"
  }
  "test-vnet-second-subnet" = {
    "name" = "test-vnet"
    "subnet" = "second-subnet"
  }
}

然后你azurerm_subnet.subnets可以如下。但是,我无法验证您的正确性azurerm_subnet,因此您可能需要进一步更改它。但是这个想法是迭代local.subnet_names_flat,这使得for_each非常容易使用:

resource "azurerm_subnet" "subnets" {

  for_each                 = local.subnet_names_flat
  
  name                      = each.value.subnet  
  resource_group_name       = data.azurerm_resource_group.network_group.name
  virtual_network_name      = each.value.vnet
  address_prefixes          = ["10.0.1.0/24"]
}


推荐阅读