首页 > 解决方案 > terraform 模块中的动态资源 for_each 输出

问题描述

Terraform v1.0.0 提供者:aws v3.49.0

我使用模块中的 for_each 创建了动态 AWS 子网资源。

资源创建工作正常,但是能够输出动态创建的资源不起作用并且找不到合适的文档。

子网模块是

resource "aws_subnet" "generic" {
  vpc_id = var.vpc_id
  cidr_block = var.cidr_block
  map_public_ip_on_launch = var.public_ip_on_launch
  tags = {
        Name = var.subnet_tag_name
        Environment = var.subnet_environment
      }
}

定义了简单的模块输出

output "subnet_id" {
    value = aws_subnet.generic.id
}

然后从根模块,我在列表变量上创建一个 for_each 循环,以从模块创建多个动态资源

module "subnets" {
  source = "../modules/networking/subnet"
  for_each = var.subnets
  vpc_id = "vpc-09d6d4c17544f3a49"
  cidr_block = each.value["cidr_block"]
  public_ip_on_launch = var.public_ip_on_launch
  subnet_environment = var.subnet_environment
  subnet_tag_name = each.value["subnet_tag_name"]
}

当我在根模块中没有定义输出的情况下运行它时,事情会正常创建。当我尝试定义输出时出现问题

output "subnets" {
    value = module.subnets.*.id
    description = "Imported VPC ID"
}

它出现了这个错误

│ Error: Unsupported attribute
│
│   on output.tf line 2, in output "subnets":
│    2:     value = module.subnets.*.id
│
│ This object does not have an attribute named "id".

我尝试了不同的输出定义。希望获得有关如何正确定义使用 for_each 模块动态创建的实例输出的指导。

标签: terraformterraform-provider-aws

解决方案


根据Terraform 文档,“splat”运算符 ( *) 只能与列表一起使用,并且由于您正在使用for_each您的输出将是一张地图。

您需要使用地图/列表理解来实现您想要的。

对于作为键/值对映射的输出(请注意,我已将输出描述更改为更有意义的内容):

output "subnets" {
    value = {
        for k, v in module.subnets:
        k => v.subnet_id
    }
    description = "Subnet IDs"
}

对于仅包含子网 ID 的列表:

output "subnets" {
    value = [
        for k, v in module.subnets:
        v.subnet_id
    ]
    description = "Subnet IDs"
}

推荐阅读