地形计数取决于目标环境中的数据



尝试最初计划或应用使用 AWS 环境中的数据值的资源时收到以下错误。

$ terraform plan 
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

------------------------------------------------------------------------
Error: Invalid count argument
on main.tf line 24, in resource "aws_efs_mount_target" "target":
24:   count = length(data.aws_subnet_ids.subnets.ids)
The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.
$ terraform --version
Terraform v0.12.9
+ provider.aws v2.30.0

我尝试使用目标选项,但似乎不适用于数据类型。

$ terraform apply -target aws_subnet_ids.subnets
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

我发现唯一有效的解决方案是:

  1. 删除资源
  2. 应用项目
  3. 重新添加资源
  4. 再次申请

这是我为测试而创建的地形配置。

provider "aws" {
version = "~> 2.0"
}
locals {
project_id = "it_broke_like_3_collar_watch"
}
terraform {
required_version = ">= 0.12"
}
resource aws_default_vpc default {
}
data aws_subnet_ids subnets {
vpc_id = aws_default_vpc.default.id
}
resource aws_efs_file_system efs {
creation_token = local.project_id
encrypted = true
}
resource aws_efs_mount_target target {
depends_on = [ aws_efs_file_system.efs ]
count = length(data.aws_subnet_ids.subnets.ids)
file_system_id = aws_efs_file_system.efs.id
subnet_id = tolist(data.aws_subnet_ids.subnets.ids)[count.index]
}

在研究了Dude0001的答案后,终于找到了答案。

简短的回答。 使用带有默认参数而不是aws_default_vpc资源的aws_vpc数据源。这是包含更改注释的工作示例。

locals {
project_id = "it_broke_like_3_collar_watch"
}
terraform {
required_version = ">= 0.12"
}
// Delete this --> resource aws_default_vpc default {}
// Add this
data aws_vpc default {
default = true
}

data "aws_subnet_ids" "subnets" {
// Update this from aws_default_vpc.default.id 
vpc_id = "${data.aws_vpc.default.id}"
}
resource aws_efs_file_system efs {
creation_token = local.project_id
encrypted = true
}
resource aws_efs_mount_target target {
depends_on = [ aws_efs_file_system.efs ]
count = length(data.aws_subnet_ids.subnets.ids)
file_system_id = aws_efs_file_system.efs.id
subnet_id = tolist(data.aws_subnet_ids.subnets.ids)[count.index]
}

我无法弄清楚的是为什么我在第一次申请时删除aws_efs_mount_target的工作有效。 这是因为在第一次应用后,aws_default_vpc已加载到状态文件中。

因此,在不更改原始 tf 文件的情况下,另一种解决方案是在第一次应用时使用目标选项:

$ terraform apply  --target aws_default_vpc.default

但是,我不喜欢这样,因为它需要在第一次部署时出现特殊情况,这对于我使用过的地形部署来说是非常独特的。

aws_default_vpc不是 TF 可以创建或销毁的资源。它是 AWS 自动为您创建的每个区域中您的账户的默认 VPC,可防止被销毁。您只能(并且需要(将其用于管理和 TF 状态。这将允许您在运行计划或应用时开始管理和检查。否则,TF 不知道资源是什么或处于什么状态,并且无法为您创建新资源,因为它是如上所述的特殊类型的受保护资源。

话虽如此,请从您在账户中部署的正确区域中获取默认 VPC ID。然后将其导入 TF 状态。然后,它应该能够检查和计算子网的数量。

例如

terraform import aws_default_vpc.default vpc-xxxxxx

https://www.terraform.io/docs/providers/aws/r/default_vpc.html

为此使用data元素对我来说看起来也有点奇怪。是否可以更改 TF 脚本以直接通过aws_default_vpc资源获取计数?

最新更新