terraform throw error:运行计划时出现“属性值类型错误”

时间:2020-07-24 17:06:00

标签: amazon-web-services terraform terraform-provider-aws

我使用https://github.com/Oxalide/terraform-fargate-example中的Terraform。

按原样运行时会出现错误:

Error: Incorrect attribute value type

  on main.tf line, in resource "aws_alb" "main":
  :   subnets         = ["${aws_subnet.public.*.id}"]

Inappropriate value for attribute "subnets": element 0: string required.

此行中的代码:

resource "aws_alb" "main" {
  name            = "tf-ecs-chat"
  subnets         = ["${aws_subnet.public.*.id}"] # <--- here is the error
  security_groups = ["${aws_security_group.lb.id}"]
}

According to the docs示例似乎正确。

resource "aws_lb" "test" {
  name               = "test-lb-tf"
  internal           = false
  load_balancer_type = "application"
  security_groups    = ["${aws_security_group.lb_sg.id}"]
  subnets            = ["${aws_subnet.public.*.id}"]
  ...
 

错误是什么意思?该怎么解决?

1 个答案:

答案 0 :(得分:0)

此示例似乎是为Terraform的较早版本编写的,不幸的是,此示例依赖于此后已修复的较早版本的配置语言错误。

表达式aws_subnet.public.*.idid的所有实例中产生aws_subnet.public属性值的列表。如果将表达式放在列表构造括号[ ]中,则Terraform会将其理解为列表列表,如下所示:

[
  [
    "i-abc123",
    "i-def456",
    "i-ghi789",
  ],
]

然后,aws_alb资源类型将其拒绝作为subnets的值,因为该参数被定义为期望一个字符串列表,而不是一个字符串列表。

由于aws_subnet.public.*.id已返回列表,您可以直接将其用作subnets的值:

  subnets         = aws_subnet.public.*.id

还请注意,我们不需要字符串插值语法,因为我们只是直接使用列表值,而不是从模板构造字符串。

示例中的security_groups参数使用类似的语法,但是在这种情况下,aws_security_group.lb.id已经是单个ID字符串而不是列表,因此[ ]在这种情况下,需要使用列表括号来构建列表 。但是,我们仍然可以通过删除不必要的模板插值语法来清理它,得到以下结果:

resource "aws_alb" "main" {
  name            = "tf-ecs-chat"
  subnets         = aws_subnet.public.*.id
  security_groups = [aws_security_group.lb.id]
}

Terraform提供程序文档中的某些示例仍在使用Terraform较早版本的语法,尤其是在所讨论的提供程序仍与较早版本兼容的情况下,我认为AWS提供商在这种情况下就是这种情况。我写这篇文章的时间。

在大多数情况下,这只会导致不必要的冗长语法,但是不幸的是,在某些情况下,示例依赖于现已修复的旧版本中的错误,因此示例本身不再能正常工作在当前的Terraform版本中。

如果您注意到类似情况,可以通过Terraform Registry中提供程序页面上的“报告问题”链接来报告错误。在这种情况下,提供者为hashicorp/aws