繁体   English   中英

Terraform如何输出使用count创建的对象ID

[英]Terraform how to output object id that were created using count

我有一个创建 2 个子网的 terraform 模块。 我需要以某种方式获取每个子网的输出。 当使用 [count.index] 作为输出块的一部分时,我收到一个错误,即无法使用 count。

那么解决方案应该是什么,因为我需要将 ec2 关联到特定的子网。

module "private_subnet" {
     source = "./modules/private_subnet"
     vpc_id = module.vpc.vpcid
     number_of_subnets = 2
     private-subnet-block = var.private-subnet-block
     tag_enviroment= var.tag_enviroment
     project_name = var.project_name }



 resource "aws_subnet" "private_subnet" {
        count = var.number_of_subnets
        cidr_block = var.private-subnet-block[count.index]
        availability_zone = var.availability_zone[count.index]
        vpc_id = var.vpc_id   
        map_public_ip_on_launch = false
        tags = {
        Name = "${var.project_name}-private-subnet-${count.index+1}"
        env = var.tag_enviroment   } }

output "privatesubnetid"{
    value = aws_subnet.private_subnet[count.index].id }

错误信息 :

错误:在非计数上下文中引用“count”││在 modules/private_subnet/output.tf 第 2 行,输出“privatesubnetid”中:│2:value = aws_subnet.private_subnet[count.index].id ││“ count”对象只能在“module”、“resource”和“data”块中使用,并且只有在设置了“count”参数时才能使用

为了在此处继续,您需要确定在没有该子网实例的情况下要在该输出值中放置什么值。


最直接的答案是只返回一个包含所有 id 的列表,如果没有,则该列表将是一个空列表:

output "private_subnet_ids" {
  value = aws_subnet.private_subnet[*].id
}

这里的[*]splat 运算符,这是一种简洁的说法,通过获取[*]左侧列表中每个元素的.id属性来构造列表,即aws_subnet.private_subnet -该资源的所有实例的列表 - 在您的情况下。


另一种选择是返回从可用区名称到子网 ID 的映射,以防模块的调用者出于某种原因需要能够区分不同的 ID:

output "private_subnet_ids" {
  value = tomap({
    for s in aws_subnet.private_subnet : s.availability_zone => s.id
  })
}

这是一个for表达式,它可能是我们之前看到的 splat 表达式的更通用形式:它将生成一个映射,其中对于aws_subnet.private_subnet s每个元素,它都会生成一个映射元素,其键为s.availability_zone ,其值为s.id

与前面的示例类似,如果没有任何子网,这将生成一个空映射。


另一个可能与您在问题中给出的示例最接近的选项是仅返回第一个子网,或者如果子网为零,则返回null

output "private_subnet_id" {
  value = length(aws_subnet.private_subnet) > 0 ? aws_subnet.private_subnet[0] : null
}

这是一个条件表达式,它根据第三个布尔表达式 ( length(aws_subnet.private_subnet) > 0 ) 的结果选择两个结果之一(在本例中为aws_subnet.private_subnet[0]null )。

这似乎不是一个特别有用的选项,因为它无法访问后续子网。 我包含它只是因为在您的示例中您使用了单数名称“私有子网 ID”而不是复数名称“私有子网 ID”,所以我想知道您是否打算以某种方式仅选择一个子网 ID。


这里也有很多其他的排列。 一般的答案是aws_subnet.private_subnet是一个对象列表,因此您可以编写在处理对象列表时有效的任何 Terraform 表达式,以对您想要产生的结果有意义的任何方式转换该列表。 但是,您必须编写一个对任意数量的子网(包括零子网)有效的表达式,以确保该模块适用于number_of_subnets的所有值。

您可以使用 Terraform splat 表达式 [1]:

output "privatesubnetid" {
    value = aws_subnet.private_subnet[*].id 
}

[1] https://www.terraform.io/language/expressions/splat

这可以帮助您:

output "database_subnets" {
  description = "IDs of database subnets"
  value       = aws_subnet.database.*.id
}

output "database_subnet_group" {
  description = "ID of database subnet group"
  value       = concat(aws_db_subnet_group.database.*.id, [""])[0]
}

要输出使用 count 创建的资源 ID,请执行以下操作:

output "private_subnet_ids" {
  value = one(aws_subnet.private_subnet[*].id)
}

上面的表达式首先使用splat operator将对象列表转换为仅包含id值的列表,根据资源计数,该列表也将包含零个或一个元素。

然后, one函数处理两种情况:

  • 如果列表只有一个值,它将返回该值。
  • 如果列表没有值,它将返回 null 表示没有值。

参考

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM