首页 > 解决方案 > 用于循环的 Terraform 嵌套

问题描述

我在这里有点挣扎,想知道这是否可能。我有一个贴花的变量,如下所示:

variable "subnets" {
  type = list(object({
    name = string
    cidr_block = string
  }))
  default = [
    {
      name = private
      cidr_block = 10.0.0.1/24
    },
    {
      name = public
      cidr_block = 10.0.0.2/24
    }
  ]
}

然后我使用数据源查询当前区域中的区域

data aws_availability_zones available {}

现在我要做的是在每个 az 区域中创建上述子网,但我似乎无法将这些区域与上述 var 结合起来。

我正在尝试的是

resource aws_suubnet subnet {
 for each  = {for idx,az.name in data.aws_availability_zones.available.names : idx => az.name}
 vpc_id    = var.vpc_id
 availability_zone = data.aws_availability_zones.available.names[each.key]
 cidr_block = (this is where I want to query my var.subnets but I don't seem to be able to do another for 
 here)
}

我希望最终得到的是 6 个子网,3 个私有子网和 3 个公共子网,每个区域各有一个。将不胜感激这里的任何帮助。谢谢

标签: amazon-web-servicesfor-loopforeachterraformeach

解决方案


我认为您的意图是动态选择两个可用的可用区域并在每个可用区域中声明一个子网。

这是可以做到的,我将在下面展示一个配置示例,但首先我想提醒一下,这是一个有潜在风险的设计,因为可用区域的集合可能会随时间而变化,因此您可能会发现无需对配置进行任何直接更改后来的 Terraform 计划建议在不同的可用区重新创建一个或两个子网。

出于这个原因,我通常建议将子网分配给可用区域,这是您有意选择并在配置中静态编码的东西,而不是动态选择它们,以确保您的配置效果随着时间的推移保持稳定,除非您有意更改它。


有了这个警告,我仍然想在这里回答一般性问题,因为在其他情况下可能会出现这种将不同长度的集合“压缩在一起”的一般想法,因此了解它的模式可能仍然有用,包括如果您最终决定将可用区列表设为变量而不是数据源查找。

variable "subnets" {
  type = list(object({
    name       = string
    cidr_block = string
  }))
}

data "aws_availability_zones" "available" {
}

locals {
  # The availability zones are returned as an unordered
  # set, so we'll sort them to be explicit that we're
  # depending on one particular ordering.
  zone_names = sort(data.aws_availabililty_zones.available.names)

  subnets = tolist([
    for i, sn in var.subnets : {
      name       = sn.name
      cidr_block = sn.cidr_block
      zone       = element(local.zone_names, i)
    }
  ])
}

上面示例中的最后一个表达式依赖于函数element它类似于 indexing likelocal.zone_names[i]但如果太大则不会返回错误,i而是会环绕并再次从区域列表中重新选择相同的项目。


推荐阅读