Terraform 如何输出使用计数创建的对象 ID
Terraform how to output object id that were created using count
我有一个创建 2 个子网的 terraform 模块。
我需要以某种方式获取每个子网的输出。当使用 [count.index] 作为输出块的一部分时,出现无法使用计数的错误。
那么解决方案应该是什么,因为我需要将 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: 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
这可以帮助你:
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]
}
您可以使用 Terraform splat 表达式 [1]:
output "privatesubnetid" {
value = aws_subnet.private_subnet[*].id
}
为了在此处继续,您需要决定在没有该子网实例的情况下要在该输出值中放置什么值。
最直接的答案是 return 所有 ID 的列表,如果有 none:
,那么它将是一个空列表
output "private_subnet_ids" {
value = aws_subnet.private_subnet[*].id
}
这里的[*]
是the splat operator,简明的说法是取左边列表的每个元素的.id
属性来构造一个列表[*]
,即 aws_subnet.private_subnet
-- 该资源的所有实例的列表 -- 在您的例子中。
另一种选择是 return 从可用区名称到子网 ID 的映射,以防您的模块的调用者出于某种原因需要能够区分不同的 ID:
output "private_subnet_ids" {
value = tomap({
for s in aws_subnet.private_subnet : s.availability_zone => s.id
})
}
这是一个 for
expression,这可能是我们之前看到的 splat 表达式的更一般形式:它将生成一个映射,其中 aws_subnet.private_subnet
s
的每个元素生成键为 s.availability_zone
且值为 s.id
.
的映射元素
与前面的示例类似,如果没有任何子网,这将生成一个空映射。
另一个可能最接近您在问题中给出的示例的选项是 return 仅 第一个 子网或 return null
如果有零个子网:
output "private_subnet_id" {
value = length(aws_subnet.private_subnet) > 0 ? aws_subnet.private_subnet[0] : null
}
这是一个 conditional expression,它根据第三个布尔表达式 (length(aws_subnet.private_subnet) > 0
).
这似乎不是一个特别有用的选项,因为它将无法访问后续子网。我包含它只是因为在您的示例中您使用了单数名称“私有子网 ID”而不是复数名称“私有子网 ID”,所以我想知道您是否打算以某种方式 select 只是其中一个子网 ID。
这里还有很多其他排列。一般的答案是 aws_subnet.private_subnet
是一个对象列表,因此您可以编写任何在处理对象列表时有效的 Terraform 表达式,以任何对您想要生成的结果有意义的方式转换该列表。但是,您必须编写对任意数量的子网(包括零个子网)都有效的表达式,以确保该模块适用于 number_of_subnets
.
的所有值
要输出使用计数创建的资源 ID,请按以下步骤操作:
output "private_subnet_ids" {
value = one(aws_subnet.private_subnet[*].id)
}
上面的表达式首先使用 splat operator
将对象列表转换为仅包含 id
值的列表,根据资源计数,该列表也将包含零个或一个元素。
one
函数然后处理两种情况:
- 如果列表只有一个值,它将return那个值。
- 如果列表没有值,它将 return null 表示没有值。
我有一个创建 2 个子网的 terraform 模块。 我需要以某种方式获取每个子网的输出。当使用 [count.index] 作为输出块的一部分时,出现无法使用计数的错误。
那么解决方案应该是什么,因为我需要将 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: 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
这可以帮助你:
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]
}
您可以使用 Terraform splat 表达式 [1]:
output "privatesubnetid" {
value = aws_subnet.private_subnet[*].id
}
为了在此处继续,您需要决定在没有该子网实例的情况下要在该输出值中放置什么值。
最直接的答案是 return 所有 ID 的列表,如果有 none:
,那么它将是一个空列表output "private_subnet_ids" {
value = aws_subnet.private_subnet[*].id
}
这里的[*]
是the splat operator,简明的说法是取左边列表的每个元素的.id
属性来构造一个列表[*]
,即 aws_subnet.private_subnet
-- 该资源的所有实例的列表 -- 在您的例子中。
另一种选择是 return 从可用区名称到子网 ID 的映射,以防您的模块的调用者出于某种原因需要能够区分不同的 ID:
output "private_subnet_ids" {
value = tomap({
for s in aws_subnet.private_subnet : s.availability_zone => s.id
})
}
这是一个 for
expression,这可能是我们之前看到的 splat 表达式的更一般形式:它将生成一个映射,其中 aws_subnet.private_subnet
s
的每个元素生成键为 s.availability_zone
且值为 s.id
.
与前面的示例类似,如果没有任何子网,这将生成一个空映射。
另一个可能最接近您在问题中给出的示例的选项是 return 仅 第一个 子网或 return null
如果有零个子网:
output "private_subnet_id" {
value = length(aws_subnet.private_subnet) > 0 ? aws_subnet.private_subnet[0] : null
}
这是一个 conditional expression,它根据第三个布尔表达式 (length(aws_subnet.private_subnet) > 0
).
这似乎不是一个特别有用的选项,因为它将无法访问后续子网。我包含它只是因为在您的示例中您使用了单数名称“私有子网 ID”而不是复数名称“私有子网 ID”,所以我想知道您是否打算以某种方式 select 只是其中一个子网 ID。
这里还有很多其他排列。一般的答案是 aws_subnet.private_subnet
是一个对象列表,因此您可以编写任何在处理对象列表时有效的 Terraform 表达式,以任何对您想要生成的结果有意义的方式转换该列表。但是,您必须编写对任意数量的子网(包括零个子网)都有效的表达式,以确保该模块适用于 number_of_subnets
.
要输出使用计数创建的资源 ID,请按以下步骤操作:
output "private_subnet_ids" {
value = one(aws_subnet.private_subnet[*].id)
}
上面的表达式首先使用 splat operator
将对象列表转换为仅包含 id
值的列表,根据资源计数,该列表也将包含零个或一个元素。
one
函数然后处理两种情况:
- 如果列表只有一个值,它将return那个值。
- 如果列表没有值,它将 return null 表示没有值。