Terraform:如何从数据类型中获取元素

Fla*_*san 2 terraform terraform-provider-aws

我对 terraform 有一个不寻常的问题。

我创建了两个 VPC,并在同一个 terraform 脚本中添加了一个私有托管区域。

我执行以下操作: data "aws_vpcs" "foo" {} 这让我获得了在该地区创建的 VPC。

通常我可以输出 VPC 的 ID,例如:

output "test" {
  value = data.aws_vpcs.foo.ids
}
Run Code Online (Sandbox Code Playgroud)

这给了我一个列表,如:

[ "vpc-0c8446a2164b7d0af", "vpc-0e7c63c3f383d115d", ]

现在,从这个列表中,我想获得第一个 VPC id:“vpc-0c8446a2164b7d0af”

问题是它不起作用。我尝试使用元素函数,如: element(data.aws_vpcs.foo.ids, 0) element([data.aws_vpcs.foo.ids], 0)

我也尝试将它分配给一个值,如:data.aws_vpcs.foo.ids[0]

它不起作用,我在 terraform 上找不到任何其他选项来帮助我解决这个问题。

我想使用第一个 VPC id 创建资源:

resource "aws_route53_zone" "private" {
 name = "example.com"

 vpc {
   vpc_id = data.aws_vpcs.foo.ids[0]
   }
}
Run Code Online (Sandbox Code Playgroud)

所以我可以从我在该地区获得的 VPC 列表中获得第一个 VPC(顺序无关紧要)。

当我运行 terraform plan 时出现错误:

Error: Invalid index

 on main.tf line 25, in resource "aws_route53_zone" "private":
 25:     vpc_id = data.aws_vpcs.foo.ids[0]

This value does not have any indices.
Run Code Online (Sandbox Code Playgroud)

Mar*_*ins 5

Terraform 区分列表值和集合值,其中集合就像集合的数学思想,它是值的无序集合,您可以询问集合中是否存在特定元素,并且您可以枚举集合中的所有元素集合,但没有索引或键可以用来查找单个项目。

aws_vpcs数据源返回一组字符串,因为没有内在的顺序在AWS的VPC:你不能把一对的VPC,并决定哪一个是“第一”,而不强加自己的分类标准。

但是,如果您没有任何特定的排序条件并且只想获取任何一个返回的 VPC,则可以使用该sort函数指示 Terraform 应按词法对 VPC id 字符串进行排序,然后将生成一个列表,您可以使用第一个元素:

resource "aws_route53_zone" "private" {
  name = "example.com"

  vpc {
    vpc_id = sort(data.aws_vpcs.foo.ids)[0]
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这本质上只是从集合中任意选择一个项目,因此只要列表永远不会改变,结果就会保持一致,但是如果将新项目添加到列表中,它可能最终会选择不同的元素,如果它碰巧在它之前选择的那个之前排序。

出于这个原因,当使用数据源检索 VPC 时,我们通常希望使用数据源检索特定的单个 VPC aws_vpc,使用足够具体的查询,它只会返回我们需要的单个 VPC。在此模型下,如果不完全是一个结果,Terraform 将返回错误,这通常比隐式做出错误选择更可取。