Terraform For_Each:如何引用创建的资源 ID

Posted

技术标签:

【中文标题】Terraform For_Each:如何引用创建的资源 ID【英文标题】:Terraform For_Each: How to reference created resource ID 【发布时间】:2021-04-15 22:18:24 【问题描述】:

我创建了一个创建 AWS 子网的模块。在模块中,我使用 for_each 循环来创建子网。我假设我可以索引给定子网的资源 ID,但似乎循环不会以可预测的顺序输出子网 ID 索引...不确定我在这里遗漏了什么。任何帮助表示赞赏!

ma​​in.tf

module "subnets" 
  source = "./modules/subnets/"
  vpc_id = aws_vpc.main.id
  subnets = [
    
      name              = "private-1a"
      cidr_block        = "10.0.0.0/28"
      availability_zone = "us-east-1a"
    ,
    
      name              = "private-1b"
      cidr_block        = "10.0.1.0/24"
      availability_zone = "us-east-1b"
    ,
    
      name              = "public-1a"
      cidr_block        = "10.0.2.0/24"
      availability_zone = "us-east-1a"
    ,
    
      name              = "public-1b"
      cidr_block        = "10.0.3.0/24"
      availability_zone = "us-east-1b"
    
  ]



output "private1a" 
  value = module.security_subnets.subnet_id[0]
 
output "private1b" 
  value = module.security_subnets.subnet_id[1]
 
output "public1a" 
  value = module.security_subnets.subnet_id[2]
 
output "public1b" 
  value = module.security_subnets.subnet_id[3]
 

模块

locals 
  subnets = 
    for i in var.subnets :
    i.name => i
  


resource "aws_subnet" "main" 
  for_each          = local.subnets
  vpc_id            = var.vpc_id
  cidr_block        = each.value.cidr_block
  availability_zone = each.value.availability_zone

  tags = merge(
    
      "Name" = format("%s", each.value.name)
    
  )



output subnet_id 
  value = values(aws_subnet.main)[*].id


【问题讨论】:

【参考方案1】:

作为一般规则,依赖于返回项目的顺序不是一个好习惯,因为如果您决定在两者之间添加某些内容或删除某些内容,这可能会导致将来出现问题。 p>

尽管如此,在您的情况下,返回项目的顺序是定义明确的。由于您使用的是values,因此顺序为:

这些值由其对应的键以字典顺序返回,因此这些值的返回顺序与它们的键从键返回的顺序相同。

【讨论】:

【参考方案2】:

subnets 变量使用映射结构而不是数组应该按索引返回值,然后解决如果顺序更改(例如删除项目)时混合值的问题:

module "subnets" 
  source = "./modules/subnets/"
  vpc_id = aws_vpc.main.id
  subnets = 
    "private-1a" = 
      name              = "private-1a"
      cidr_block        = "10.0.0.0/28"
      availability_zone = "us-east-1a"
    ,
    "private-1b" = 
      name              = "private-1b"
      cidr_block        = "10.0.1.0/24"
      availability_zone = "us-east-1b"
    ,
    "public-1a" = 
      name              = "public-1a"
      cidr_block        = "10.0.2.0/24"
      availability_zone = "us-east-1a"
    ,
    "public-1b" = 
      name              = "public-1b"
      cidr_block        = "10.0.3.0/24"
      availability_zone = "us-east-1b"
    
  



output "private1a" 
  value = module.security_subnets.subnet_id["private-1a"]
 

// and so on

【讨论】:

以上是关于Terraform For_Each:如何引用创建的资源 ID的主要内容,如果未能解决你的问题,请参考以下文章

Terraform : for_each 一个一个

如何在 terraform 中正确使用 for_each 中的 each.value?

使用 terraform 在 for_each 嵌套资源中循环

Terraform 模块输出用作其他模块中的输入,特别是 for_each

将 aws 资源导入具有 for_each 的 terraform 模块

Terraform 因 for_each 参数无效/给定的“for_each”参数值不合适而失败