Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Terraform:如何从数据类型获取元素_Terraform_Terraform Provider Aws - Fatal编程技术网

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

Terraform:如何从数据类型获取元素,terraform,terraform-provider-aws,Terraform,Terraform Provider Aws,我对地形有一个不寻常的问题 我创建了两个VPC,并在同一个terraform脚本中添加一个私有托管区域 我做了以下工作: data“aws_vpcs”“foo”{} 这是给我在该地区创建的专有网络 通常我可以输出VPC的ID,如: output "test" { value = data.aws_vpcs.foo.ids } 这给了我一个列表,比如: [ “vpc-0c8446a2164b7d0af”, “vpc-0e7c63c3f383d115d”, ] 现在,我想从这个列表中获得第一个

我对地形有一个不寻常的问题

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

我做了以下工作:
data“aws_vpcs”“foo”{}
这是给我在该地区创建的专有网络

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

output "test" {
  value = data.aws_vpcs.foo.ids
}
这给了我一个列表,比如:

[ “vpc-0c8446a2164b7d0af”, “vpc-0e7c63c3f383d115d”, ]

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

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

我还尝试将其赋值为如下值:data.aws\u vpcs.foo.ids[0]

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

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

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

 vpc {
   vpc_id = data.aws_vpcs.foo.ids[0]
   }
}
因此,我可以从我在该地区获得的专有网络列表中获得第一个专有网络(顺序无关紧要)

当我运行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.

如果在同一脚本中使用terraform创建VPC,则不需要数据提供程序。相反,您应该直接从资源访问ID。请参阅以了解类似情况以及如何解决此问题的更多详细信息。

元素不起作用,因为vpc id列表不是一个列表,而是一组字符串。因此,以下方法不起作用。否则,此命令中没有问题

 "${element(data.aws_vpcs.foo.ids, 0)}"
然而,我找到了另一种方法来从使用sort中获取元素。但同样,它是被分类的。如果您对任何专有网络id都没有问题,那么它应该没有问题

我仍然更喜欢Falk的建议,因为您试图在同一个脚本中提取专有网络id,所以您可以直接访问专有网络,然后获取id

作为练习,我将脚本放在下面以多种方式访问id。快乐的脚本

resource "aws_vpc" "vpc1" {
  cidr_block = "10.20.0.0/16"
  tags = {
    name = "tf_vpc"
  }
}

resource "aws_vpc" "vpc2" {
  cidr_block = "10.30.0.0/16"
  tags = {
    name = "tf_vpc_2"
  }
}


data "aws_vpcs" foo{}

output "test" {
  value = "${data.aws_vpcs.foo.ids}"
}
output "test1" {
  value = "${aws_vpc.vpc1.id}"
}

output "test2" {
  value = "${aws_vpc.vpc2.id}"
}

output "counter" {
  value = "${length(data.aws_vpcs.foo.ids)}"

}


output "myvpcID" {
  value = sort(data.aws_vpcs.foo.ids)[0]
}

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

aws_vpcs
数据源返回一组字符串,因为aws中的vpcs没有固有的顺序:如果不强制实施自己的排序标准,您无法获取一对vpcs并决定哪一个是“第一”

但是,如果您没有任何特定的排序标准,只希望获取任何一个返回的专有网络,您可以使用
sort
功能指示Terraform应对专有网络id字符串进行排序,然后将生成一个列表,您可以获取以下第一个元素:

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

  vpc {
    vpc_id = sort(data.aws_vpcs.foo.ids)[0]
  }
}
但要注意,这本质上只是从集合中任意选择一个项目,因此只要列表从未更改,结果将是一致的。但是,如果将新项目添加到列表中,如果它恰好在之前选择的项目之前排序,则可能会选择不同的元素


因此,当使用数据源检索专有网络时,我们通常希望使用
aws_VPC
数据源检索特定的单个专有网络,使用特定的查询,它将只返回我们需要的单个专有网络。在这个模型下,如果没有一个结果,Terraform将返回一个错误,这通常比隐式地做出错误选择更可取。

当你说它不工作时,你会得到什么错误?您可以编辑您的问题以显示
aws\U vpcs
数据源的地形代码吗?您应该编辑您的问题以包含错误,不要在评论中发布。这是正确的-您可能应该直接引用专有网络资源:
vpc\u id=aws\u vpc.vpc\u one.id
vpc\u id=aws\u vpc.vpc\u two.id
。对于其他类型的资源(您希望在所有VPC中创建的资源),使用数据源可能有助于循环(即使用
for_each
count
)。我同意输出是一个集合是有意义的,但在文档中它说返回一个列表,甚至提供了一个使用索引访问输出的示例。此文档是否错误?是的,该文档似乎不正确。它看起来是为Terraform 0.11编写的,
元素
函数可以隐式地将集合转换为列表;本质上,它自动调用了
sort
,使结果看起来是一个有序列表,即使它实际上只是选择了一个任意元素。