Terraform Splat 表达给予 "Invalid template interpolation value"

Terraform Splat Expression Giving "Invalid template interpolation value"

我在 Terraform 中使用数据源来获取我的安全组的 ID 列表:

data "aws_security_groups" "test" {
  filter {
    name   = "group-name"
    values = ["the-name"]
  }
}

output "security_group_id" {
  value = "The id is ${data.aws_security_groups.test.ids[*]}"
}

但是,这给了我以下错误:

Error: Invalid template interpolation value

on main.tf line 11, in output "security_group_id":
  11:   value = "The id is ${data.aws_security_groups.test.ids[*]}"
    |----------------
    | data.aws_security_groups.test.ids is list of string with 1 element

Cannot include the given value in a string template: string required.

但是如果我改用 data.aws_security_groups.test.ids[0] 它会显示 ID。

有人可以帮我显示 ID 列表吗?

首先,我想指出,如果您不想,则根本不需要将此列表与字符串消息组合,因为 Terraform 将接受任何类型的输出值:

output "security_group_ids" {
  value = data.aws_security_groups.test.ids
}

如果将它们包含为更大字符串的一部分对于您的潜在问题很重要,那么您需要决定如何在单个字符串中显示这些多个 ID。有多种不同的方法可以做到这一点,具体取决于您打算如何处理这些信息。

一个相对直接的答案是使用 jsonencode 使字符串包含列表的 JSON 表示,如下所示:

output "security_group_id_message" {
  value = "The ids are ${jsonencode(data.aws_security_groups.test.ids)}"
}

如果您想要更人性化的演示,那么您可能更愿意使用多行字符串,在这种情况下,您可以使用 string templates.

自定义输出
output "security_group_id_message" {
  value = <<-EOT
  The ids are:
  %{ for id in data.aws_security_groups.test.ids ~}
  - ${id}
  %{ endfor ~}
  EOT
}

或者,对于介于两者之间的某个答案,您可以使用 join 将值与一个简单的分隔符连接在一起,如下所示:

output "security_group_id_message" {
  value = "The ids are ${join(",", data.aws_security_groups.test.ids)}"
}

请注意,我在所有这些示例中都从您的引用中删除了 [*],因为它在这里并没有真正做任何事情:data.aws_security_groups.test.ids 已经是一个可迭代的集合,因此与我在上面的示例中使用的所有语言功能。

IIRC 提供者认为此 ids 属性是一组字符串而不是字符串列表,因此 [*] 后缀在其他情况下可能对强制转换该集合很有用如果您需要以这种方式输入列表,则将其放入列表中,尽管如果这是您的意图,那么我建议改用以下之一,以便将来更清楚 reader 它的作用:

  • sort(data.aws_security_groups.test.ids)(如果按词法排序对行为很重要;无论如何 Terraform 默认使用词法排序,但是调用 sort 是对 reader 不熟悉的人的一个很好的提示使用 Terraform 查找该函数以查看实际排序顺序。)
  • tolist(data.aws_security_groups.test.ids)(当它是一组字符串时,在功能上等同于上面的 sort,但避免了特定顺序很重要的暗示,如果重要的是它是一个列表,而不管订购)