我使用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}"]
...
错误是什么意思?该怎么解决?
答案 0 :(得分:0)
此示例似乎是为Terraform的较早版本编写的,不幸的是,此示例依赖于此后已修复的较早版本的配置语言错误。
表达式aws_subnet.public.*.id
从id
的所有实例中产生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
。