количество терраформ зависит от данных из целевой среды - PullRequest
1 голос
/ 02 октября 2019

При попытке изначально спланировать или применить ресурс, использующий значения данных из среды 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. применить снова

Вот конфигурация terraform, которую я создал для тестирования.

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]
}

Ответы [ 2 ]

0 голосов
/ 02 октября 2019

Наконец выяснили ответ после исследования ответа Dude0001.

Короткий ответ. Используйте источник данных aws_vpc с аргументом по умолчанию вместо ресурса aws_default_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

Однако мне это не нравится, поскольку для первого развертывания требуется особый случай, который довольно уникален для развертываний terraform, с которыми я работал.

0 голосов
/ 02 октября 2019

aws_default_vpc не является ресурсом, который TF может создавать или уничтожать. Это VPC по умолчанию для вашей учетной записи в каждом регионе, который AWS создает автоматически для вас, который защищен от уничтожения. Вы можете только (и должны) принять его в управление и ваше состояние TF. Это позволит вам начать управление и проверять, когда вы запускаете план или подаете заявку. В противном случае TF не знает, что такое ресурс или в каком состоянии он находится, и он не может создать новый для вас, поскольку это особый тип защищенного ресурса, как описано выше.

С учетом сказанного, перейдитеполучите идентификатор VPC по умолчанию из правильного региона, который вы развертываете в своей учетной записи. Затем импортируйте его в состояние 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?

...