地形版本0.11.13
错误:刷新状态时出错:出现1个错误:
- data.aws_subnet.private_subnet:无法计算"count"的值
VPC代码生成了上面的错误:
resources.tf
data "aws_subnet_ids" "private_subnet_ids" {
vpc_id = "${module.vpc.vpc_id}"
}
data "aws_subnet" "private_subnet" {
count = "${length(data.aws_subnet_ids.private_subnet_ids.ids)}"
#count = "${length(var.private-subnet-mapping)}"
id = "${data.aws_subnet_ids.private_subnet_ids.ids[count.index]}"
}
将上述代码改变为使用计数="0"${length(var.private-subnet-mapping(}";,我成功配置了VPC。但是,vpc_private_subnets_ids的输出为空。vpc_private_subnets_ids=[]
代码提供了VPC,但得到了空的VPC_private_subnets_ids:列表
resources.tf
data "aws_subnet_ids" "private_subnet_ids" {
vpc_id = "${module.vpc.vpc_id}"
}
data "aws_subnet" "private_subnet" {
#count = "${length(data.aws_subnet_ids.private_subnet_ids.ids)}"
count = "${length(var.private-subnet-mapping)}"
id = "${data.aws_subnet_ids.private_subnet_ids.ids[count.index]}"
}
outputs.tf
output "vpc_private_subnets_ids" {
value = ["${data.aws_subnet.private_subnet.*.id}"]
}
The output of vpc_private_subnets_ids:
vpc_private_subnets_ids = []
我需要vpc_private_subnets_ids的值。在成功提供VPC使用该线路之后,count="0"${length(var.private-subnet-mapping(}";,我把代码改回count="0"${length(data.aws_subnet_ids.private_subnet_ids.ids(}";。terraform应用,我得到了列表vpc_private_subnets_ids的值,没有出现以上错误。
vpc_private_subnets_ids = [
subnet-03199b39c60111111,
subnet-068a3a3e76de66666,
subnet-04b86aa9dbf333333,
subnet-02e1d8baa8c222222
......
]
我不能使用count="0"${length(data.aws_subnet_ids.private_subnet_ids.ids(}";当我提供VPC时。但是,我可以在VPC提供后使用它。有线索吗?
这里的问题似乎是您的VPC尚未创建,因此读取data "aws_subnet_ids" "private_subnet_ids"
数据源必须等到应用步骤,这反过来意味着子网的数量未知,因此data "aws_subnet" "private_subnet"
实例的数量是不可预测的,Terraform返回此错误。
如果此配置也是负责创建这些子网的配置,那么更好的设计是直接引用子网对象。如果您的module.vpc
也是创建子网的模块,那么我建议将子网ID导出为该模块的输出。例如:
output "subnet_ids" {
value = "${aws_subnet.example.*.id}"
}
然后,您的调用模块可以直接从module.vpc.subnet_ids
获取这些id,而不需要额外的API调用来查找它们:
output "vpc_private_subnets_ids" {
value = ["${module.vpc.subnet_ids}"]
}
除了关于count
的错误之外,您显示的配置也有竞争条件,因为data "aws_subnet_ids" "private_subnet_ids"
块只取决于VPC本身,而不取决于单个VPC,因此Terraform可能在创建子网之前读取该数据源。通过模块输出导出子网ID意味着对module.vpc.subnet_ids
的任何引用都间接依赖于所有子网,因此这些下游操作将等待,直到创建了所有子网。
一般来说,一个特定的Terraform配置应该是管理一个对象或通过数据源读取该对象,而不是同时管理这两个对象。如果两者同时进行,有时可能会奏效,但很容易无意中引入这样的竞争条件,Terraform无法判断data
资源正试图消耗参与同一计划的另一个resource
块的结果。