Нельзя использовать идентификаторы подсети, созданные в той же конфигурации terraform с aws_route_table_association

Я пытаюсь использовать идентификаторы подсети, созданные блоком resource "aws_subnet" "public" {...}, в блоке resource "aws_route_table_association" "public" {...}, но выдает ошибку:

Error: Invalid for_each argument
 
   on main.tf line 69, in resource "aws_route_table_association" "public":
   69:   for_each       = toset(tolist([for subnet in aws_subnet.public : subnet.id]))
     ├────────────────
     │ aws_subnet.public is object with 3 attributes
 
 The "for_each" set includes values derived from resource attributes
 that cannot be determined until apply, and so Terraform cannot determine
 the full set of keys that will identify the instances of this resource.
 
 When working with unknown values in for_each, it's better to use a map
 value where the keys are defined statically in your configuration and 
 where only the values contain   apply-time results.

 Alternatively, you could use the -target planning option to first apply
 only the resources that the for_each value depends on, and then apply a
 second time to fully converge.

Как показано в моем файле конфигурации terraform ниже, я использовал depends_on = [aws_subnet.public] в resource "aws_route_table_association" "public", ожидая, что идентификаторы подсети будут созданы до запуска ассоциаций.

Это работает, как предлагается в сообщении об ошибке, если я выполняю два шага, например:

terraform apply -target=aws_subnet.public -target=aws_subnet.private -auto-approve
terraform apply -auto-approve

Предложения по сопоставлению мне не совсем понятны, но я думаю, что потребуется сопоставить с использованием имени региона AWS, которое я не хочу использовать, так как мне нужно запускать это в любом регионе. Если я могу использовать сопоставление с переменной aws_region, я согласен с этим.

Как я могу сделать это за один прогон?

Файл конфигурации main.tf:

// provider
provider "aws" {
  region                   = var.aws_region
  shared_credentials_files = ["~/.aws/credentials"]
  #profile                  = var.aws_profile # using `default` profile
}

// data
data "aws_availability_zones" "available" {
  state = "available"

  filter {
    name   = "zone-type"
    values = ["availability-zone"]
  }
}

//variables
variable "aws_region" {
  type    = string
  default = "us-east-1"
}

variable "environment" {
  type        = string
  description = "Deployment Environment (e.g. dev, prod, etc.)"
  default     = "dev"
}

variable "vpc_cidr" {
  type        = string
  description = "AWS VPC CIDR"
  default     = "10.0.0.0/16"
}

variable "public_subnet_cidrs" {
  type    = list(string)
  default = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
}

// vpc
resource "aws_vpc" "this" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  tags = {
    Name = "${var.environment}-vpc"
  }
}

// public subnets, public route table, public subnet associations
resource "aws_subnet" "public" {
  for_each          = toset(var.public_subnet_cidrs)
  cidr_block        = each.value
  vpc_id            = aws_vpc.this.id
  availability_zone = data.aws_availability_zones.available.names[index(var.public_subnet_cidrs, each.value)]
  tags = {
    Name = "Public-Subnet-${index(var.public_subnet_cidrs, each.value) + 1}"
  }
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.this.id
  tags = {
    Name = "Public-RouteTable"
  }
}

resource "aws_route_table_association" "public" {
  for_each       = toset(tolist([for subnet in aws_subnet.public : subnet.id])) # touples --> list --> set
  route_table_id = aws_route_table.public.id
  subnet_id      = each.value
  depends_on     = [aws_subnet.public]
}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете просто использовать for_each = aws_subnet.public:

resource "aws_route_table_association" "public" {
  for_each       = aws_subnet.public
  route_table_id = aws_route_table.public.id
  subnet_id      = each.value.id
}

@ Рафик Нет проблем. Рад, что ответ помог.

Marcin 01.04.2023 03:00

Другие вопросы по теме