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 风格,因此在上面的示例中,我将变量重命名为 routeROUTE 也可以,但这是一种不寻常的命名 Terraform 变量的方式。