简体   繁体   English

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

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

I have a terraform module that creates 2 subnets.我有一个创建 2 个子网的 terraform 模块。 I need somehow to get the output for each subnet.我需要以某种方式获取每个子网的输出。 When using the [count.index] as part of the output block I'm getting an error that count can not be used.当使用 [count.index] 作为输出块的一部分时,我收到一个错误,即无法使用 count。

So what should be the solution since I need to associate ec2 to a specific subnet.那么解决方案应该是什么,因为我需要将 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 }

Error message :错误信息 :

Error: Reference to "count" in non-counted context │ │ on modules/private_subnet/output.tf line 2, in output "privatesubnetid": │ 2: value = aws_subnet.private_subnet[count.index].id │ │ The "count" object can only be used in "module", "resource", and "data" blocks, and only when the "count" argument is set错误:在非计数上下文中引用“count”││在 modules/private_subnet/output.tf 第 2 行,输出“privatesubnetid”中:│2:value = aws_subnet.private_subnet[count.index].id ││“ count”对象只能在“module”、“resource”和“data”块中使用,并且只有在设置了“count”参数时才能使用

In order to proceed here you will need to decide what value you want to place in that output value in the situation where there are no instances of that subnet.为了在此处继续,您需要确定在没有该子网实例的情况下要在该输出值中放置什么值。


The most straightforward answer would be to just return a list of all of the ids, which will then be an empty list in the case where there are none:最直接的答案是只返回一个包含所有 id 的列表,如果没有,则该列表将是一个空列表:

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

The [*] here is the splat operator , which is a concise way of saying to construct a list by taking the .id attribute of each element of the list on the left side of [*] , which is aws_subnet.private_subnet -- the list of all instances of that resource -- in your case.这里的[*]splat 运算符,这是一种简洁的说法,通过获取[*]左侧列表中每个元素的.id属性来构造列表,即aws_subnet.private_subnet -该资源的所有实例的列表 - 在您的情况下。


Another option would be to return a map from availability zone name to subnet ID, in case the caller of your module needs to be able to distinguish between the different IDs for some reason:另一种选择是返回从可用区名称到子网 ID 的映射,以防模块的调用者出于某种原因需要能够区分不同的 ID:

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

This is a for expression , which is perhaps a more general form of the splat expression we saw previously: it will produce a map where for each element of aws_subnet.private_subnet s it produces an element of the map whose key is s.availability_zone and whose value is s.id .这是一个for表达式,它可能是我们之前看到的 splat 表达式的更通用形式:它将生成一个映射,其中对于aws_subnet.private_subnet s每个元素,它都会生成一个映射元素,其键为s.availability_zone ,其值为s.id

Similar to the previous example, this will produce an empty map if there aren't any subnets.与前面的示例类似,如果没有任何子网,这将生成一个空映射。


One more option that is perhaps closest to the example you gave in your question is to either return the first subnet only or to return null if there are zero subnets:另一个可能与您在问题中给出的示例最接近的选项是仅返回第一个子网,或者如果子网为零,则返回null

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

This is a conditional expression , which chooses one of two results ( aws_subnet.private_subnet[0] and null in this case) based on the result of a third boolean expression ( length(aws_subnet.private_subnet) > 0 ).这是一个条件表达式,它根据第三个布尔表达式 ( length(aws_subnet.private_subnet) > 0 ) 的结果选择两个结果之一(在本例中为aws_subnet.private_subnet[0]null )。

This one doesn't seem like a particularly useful option since it would leave no way to access the subsequent subnets.这似乎不是一个特别有用的选项,因为它无法访问后续子网。 I included it only because in your example you used the singular name "private subnet ID" instead of the plural name "private subnet IDs" and so I wondered if you were intending to select just one of the subnet IDs somehow.我包含它只是因为在您的示例中您使用了单数名称“私有子网 ID”而不是复数名称“私有子网 ID”,所以我想知道您是否打算以某种方式仅选择一个子网 ID。


There are lots of other permutations here too.这里也有很多其他的排列。 The general answer is that aws_subnet.private_subnet is a list of objects and so you can write any Terraform expression that is valid when working with lists of objects, to transform that list in whatever way makes sense for the result you want to produce.一般的答案是aws_subnet.private_subnet是一个对象列表,因此您可以编写在处理对象列表时有效的任何 Terraform 表达式,以对您想要产生的结果有意义的任何方式转换该列表。 However, you must write an expression that is valid for any number of subnets -- including zero subnets -- to ensure that the module will work for all values of number_of_subnets .但是,您必须编写一个对任意数量的子网(包括零子网)有效的表达式,以确保该模块适用于number_of_subnets的所有值。

You can use Terraform splat expression [1]:您可以使用 Terraform splat 表达式 [1]:

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

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

This can help you:这可以帮助您:

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]
}

To output resource id that were created using count, do it like this:要输出使用 count 创建的资源 ID,请执行以下操作:

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

The expression above first uses the splat operator to transform the list of objects into a list of just id values, which will also have either zero or one elements depending on the resource count.上面的表达式首先使用splat operator将对象列表转换为仅包含id值的列表,根据资源计数,该列表也将包含零个或一个元素。

The one function then deals with the two cases:然后, one函数处理两种情况:

  • If the list has only one value, it'll return that value.如果列表只有一个值,它将返回该值。
  • If the list has no values, it'll return null to represent the absence of a value.如果列表没有值,它将返回 null 表示没有值。

Refernce 参考

暂无
暂无

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

相关问题 如何使用从一个 Terraform 计划创建到另一个 Terraform 计划的 VPC id 和子网 id 值 - How to use the VPC id and subnets id values which were created from one Terraform plan to in another Terraform plan Terraform 配置未使用其他文件中的 output 来获取已创建的资源,而是尝试重新创建它并失败(安全组 ID) - Terraform config isn't using output from other file for already created resource, instead tries to recreate it and fails (security group id) Terraform For_Each:如何引用创建的资源 ID - Terraform For_Each: How to reference created resource ID Terraform 13、如何引用使用count的模块的单个实例的output - Terraform 13, how to reference the output of a single instance of a module that uses count Terraform 计数功能使用 IF / OR - Terraform Count Functionality Using IF / OR 如何将 aws_instance 资源创建的 EC2 实例 ID 传递到文件中,并使用 Terraform 将其放置在 EC2 实例中? - How to pass the EC2 instance ID created by an aws_instance resource into a file and place it inside an EC2 instance using Terraform? Terraform output 用于 eip 分配 id - Terraform output for eip allocation id terraform - 如何为 lambda 添加 s3 对象创建触发器 - terraform - how to add s3 Object Created trigger for lambda 在 terraform object 中使用 output 值 - Use output value in terraform object 如何使用 terraform 从创建的实例创建 AWS AMI? - How to create AWS AMI from created instance using terraform?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM