Terraform 属性“route”的值不合适

Luk*_*jun 1 amazon-web-services terraform terraform-provider-aws

对 terraform 相对较新,目前正在尝试在 AWS 中构建云基础设施。\n当我使用资源aws_route_table ( https://registry.terraform.io/providers/ ) 文档中的官方示例(略有更改)时,出现错误hashcorp/aws/latest/docs/resources/route_table

\n
resource "aws_route_table" "prod-route-table" {\n  vpc_id = aws_vpc.prod-vpc.id\n\n  route = [{\n      # Route all Traffic to the internet gateway\n      cidr_block = "0.0.0.0/0"\n      gateway_id = aws_internet_gateway.gw.id\n  },{\n      ipv6_cidr_block = "::/0"\n      gateway_id = aws_internet_gateway.gw.id\n  }]\n  \n}\n
Run Code Online (Sandbox Code Playgroud)\n

我收到以下错误消息

\n
Error: Incorrect attribute value type\n\xe2\x94\x82 Inappropriate value for attribute "route": element 0: attributes "carrier_gateway_id",\n\xe2\x94\x82 "destination_prefix_list_id", "egress_only_gateway_id", "instance_id", "ipv6_cidr_block",\n\xe2\x94\x82 "local_gateway_id", "nat_gateway_id", "network_interface_id", "transit_gateway_id", "vpc_endpoint_id",\n\xe2\x94\x82 and "vpc_peering_connection_id" are required.\n
Run Code Online (Sandbox Code Playgroud)\n

添加所有这些属性可以解决该错误,但这会极大地破坏代码。\n以不同方式编写它(请参阅下文)不会导致任何错误,terraform AWS 文档是否不正确,因为它们清楚地说明了第一种编写方式?

\n
resource "aws_route_table" "prod-route-table" {\n  vpc_id = aws_vpc.prod-vpc.id\n\n  route {\n      # Route all Traffic to the internet gateway\n      cidr_block = "0.0.0.0/0"\n      gateway_id = aws_internet_gateway.gw.id\n  }\n  route{\n      ipv6_cidr_block = "::/0"\n      gateway_id = aws_internet_gateway.gw.id\n  }\n  \n}\n
Run Code Online (Sandbox Code Playgroud)\n

我正在使用 terraform v1.0.10 和 aws 提供程序版本 = "3.63.0"
\n提前致谢

\n

Mar*_*ins 5

该参数的文档提到它使用遗留属性作为块模式,这是 Terraform v0.12 的保留,适用于某些情况,在这些情况下提供程序依赖于能够在嵌套块语法中写入某些参数(就像在您的第二个中一样)示例)和属性语法(如第一个示例中所示)。

文档示例中当前显示的语法以及您问题中的第一个示例与有关如何编写固定值(而不是动态值)的建议相反,因此实际上您在此处显示的第二个示例是就一般 Terraform 文档而言,这是首选方式。

resource "aws_route_table" "example" {
  vpc_id = aws_vpc.example.id

  route {
    cidr_block = "10.0.1.0/24"
    gateway_id = aws_internet_gateway.example.id
  }
  route {
    ipv6_cidr_block        = "::/0"
    egress_only_gateway_id = aws_egress_only_internet_gateway.example.id
  }

  tags = {
    Name = "example"
  }
}
Run Code Online (Sandbox Code Playgroud)

可能 AWS 提供商文档作者在这里使用了属性语法,以便显示与设置的特殊情况的对称性,route = []以明确声明根本不应该有路由,因为不幸的是(由于历史原因)完全省略此参数意味着忽略任何现有的远程 API 中的路由,而不是删除远程 API 中的所有现有路由。

有关您在后续部分带有参数语法的任意表达式中看到的行为的更多信息:

由于像这样的参数声明完全覆盖任何默认值的规则,当直接创建对象列表表达式时,可选参数的通常处理不适用,因此必须为所有参数分配一个值,即使它是一个值显式空:

example = [
  {
    # Cannot omit foo in this case, even though it would be optional in the
    # nested block syntax.
    foo = null
  },
]
Run Code Online (Sandbox Code Playgroud)

随着时间的推移,提供商将逐步淘汰这种旧模式,但必须谨慎行事,因为这可能会对某些现有配置造成重大变化。不幸的是,在那之前,对于某些特定的提供程序属性来说,这是一个令人困惑的粗糙边缘,尽管它们至少应该全部链接到我上面链接的相关文档页面,以注意它们的行为与正常的 Terraform 参数处理行为不匹配。