Terraform 如何修复属性 "route":需要一组对象
Terraform how to fix attribute "route": set of object required
我有这个 terraform
模块 route_table.tf
我需要使用。如下所示:
resource "aws_route_table" "aws_route_table" {
# route {
# cidr_block = "0.0.0.0/0"
# gateway_id = var.GATEWAY_ID
# }
route = var.ROUTE
tags = var.ROUTE_TABLE_TAGS
vpc_id = var.VPC_ID
}
并且我在 inputs.tf
中定义了变量 ROUTE
:
variable "ROUTE" {
type = object({ cidr_block=string, gateway_id=string })
}
我在 main.tf
中传递这些值,如下所示:
module "route_tables_public" {
source = "./modules/route_tables"
ROUTE = {
cidr_block = "0.0.0.0/0"
gateway_id = var.GATEWAY_ID
}
ROUTE_TABLE_TAGS = { "Name" : "mlb-rt-public" , "Project" : "mlb"}
VPC_ID = module.ecs_vpc.vpc_id
}
但是我收到这个错误:
Inappropriate value for attribute "route": set of object required.
有人可以帮我解决这个问题吗?
您的var.ROUTE
是单个对象,但它应该是对象列表。所以你可以试试:
variable "ROUTE" {
type = list(object({ cidr_block=string, gateway_id=string }))
}
然后
module "route_tables_public" {
source = "./modules/route_tables"
ROUTE = [{
cidr_block = "0.0.0.0/0"
gateway_id = var.GATEWAY_ID
}]
ROUTE_TABLE_TAGS = { "Name" : "mlb-rt-public" , "Project" : "mlb"}
VPC_ID = module.ecs_vpc.vpc_id
}
更新
您的 aws_route_table
应该是:
resource "aws_route_table" "aws_route_table" {
dynamic "route" {
for_each = var.ROUTE
content {
cidr_block = route.value.cidr_block
gateway_id = route.value.gateway_id
}
}
tags = var.ROUTE_TABLE_TAGS
vpc_id = var.VPC_ID
}
我建议不要像这样直接将变量值分配给复杂的资源类型参数,因为如果 route
参数的架构在将来增长以包含其他属性,那么您的模块将无法通过验证。
相反,最好让变量的类型独立于 route
块模式并在它们之间显式转换,这样只要新版本的提供程序不引入,它就可以工作该块的新 required 参数。
variable "route" {
type = object({
cidr_block = string
gateway_id = string
})
}
resource "aws_route_table" "aws_route_table" {
# ...
route {
cidr_block = var.route.cidr_block
gateway_id = var.route.gateway_id
}
}
这是可行的,因为它使用对象的两个属性构造一个符合 route
块架构的新对象,而您的示例失败是因为您试图直接分配输入对象 到该参数,这将要求您完全匹配目标类型。
请注意,全部大写命名变量不是惯用的 Terraform 风格,因此在上面的示例中,我将变量重命名为 route
。 ROUTE
也可以,但这是一种不寻常的命名 Terraform 变量的方式。
我有这个 terraform
模块 route_table.tf
我需要使用。如下所示:
resource "aws_route_table" "aws_route_table" {
# route {
# cidr_block = "0.0.0.0/0"
# gateway_id = var.GATEWAY_ID
# }
route = var.ROUTE
tags = var.ROUTE_TABLE_TAGS
vpc_id = var.VPC_ID
}
并且我在 inputs.tf
中定义了变量 ROUTE
:
variable "ROUTE" {
type = object({ cidr_block=string, gateway_id=string })
}
我在 main.tf
中传递这些值,如下所示:
module "route_tables_public" {
source = "./modules/route_tables"
ROUTE = {
cidr_block = "0.0.0.0/0"
gateway_id = var.GATEWAY_ID
}
ROUTE_TABLE_TAGS = { "Name" : "mlb-rt-public" , "Project" : "mlb"}
VPC_ID = module.ecs_vpc.vpc_id
}
但是我收到这个错误:
Inappropriate value for attribute "route": set of object required.
有人可以帮我解决这个问题吗?
您的var.ROUTE
是单个对象,但它应该是对象列表。所以你可以试试:
variable "ROUTE" {
type = list(object({ cidr_block=string, gateway_id=string }))
}
然后
module "route_tables_public" {
source = "./modules/route_tables"
ROUTE = [{
cidr_block = "0.0.0.0/0"
gateway_id = var.GATEWAY_ID
}]
ROUTE_TABLE_TAGS = { "Name" : "mlb-rt-public" , "Project" : "mlb"}
VPC_ID = module.ecs_vpc.vpc_id
}
更新
您的 aws_route_table
应该是:
resource "aws_route_table" "aws_route_table" {
dynamic "route" {
for_each = var.ROUTE
content {
cidr_block = route.value.cidr_block
gateway_id = route.value.gateway_id
}
}
tags = var.ROUTE_TABLE_TAGS
vpc_id = var.VPC_ID
}
我建议不要像这样直接将变量值分配给复杂的资源类型参数,因为如果 route
参数的架构在将来增长以包含其他属性,那么您的模块将无法通过验证。
相反,最好让变量的类型独立于 route
块模式并在它们之间显式转换,这样只要新版本的提供程序不引入,它就可以工作该块的新 required 参数。
variable "route" {
type = object({
cidr_block = string
gateway_id = string
})
}
resource "aws_route_table" "aws_route_table" {
# ...
route {
cidr_block = var.route.cidr_block
gateway_id = var.route.gateway_id
}
}
这是可行的,因为它使用对象的两个属性构造一个符合 route
块架构的新对象,而您的示例失败是因为您试图直接分配输入对象 到该参数,这将要求您完全匹配目标类型。
请注意,全部大写命名变量不是惯用的 Terraform 风格,因此在上面的示例中,我将变量重命名为 route
。 ROUTE
也可以,但这是一种不寻常的命名 Terraform 变量的方式。