Как запустить этот терраформ, вложенный в цикл?

Я пытался заставить эту работу работать, но просто не могу этого понять. Можете ли вы помочь? Он должен перебирать частный и общедоступный маршрут, а также cidr_blocks для каждого типа маршрута.

locals {
  routes = {
    private = {
      route_table_ids  = module.vpc.private_route_table_ids
      cidr_blocks      = ["10.1.0.0/16", "10.2.0.0/16", "10.5.0.0/16"]
    }
    public = {
      route_table_ids  = module.vpc.public_route_table_ids
      cidr_blocks      = ["10.1.0.0/16", "10.2.0.0/16", "10.5.0.0/16"]
    }
  }
}

resource "aws_route" "vpc_route" {
  for_each = {
    for route in local.routes :
      for cidr in route.cidr_blocks : "${route}-${cidr}" => {
        route_table_id         = route.route_table_ids
        destination_cidr_block = cidr
      }
  }

  route_table_id         = each.value.route_table_id
  destination_cidr_block = each.value.destination_cidr_block
  gateway_id             = module.vpc.vgw_id
}

Ошибка, которую я получаю здесь:

╷
│ Error: Invalid 'for' expression
│ 
│   on routes.tf line 17, in resource "aws_route" "vpc_meta_route":
│   15:   for_each = {
│   16:     for route in local.routes :
│   17:       for cidr in route.cidr_blocks : "${route}-${cidr}" => {
│   18:         route_table_id         = route.route_table_ids
│   19:         destination_cidr_block = cidr
│   20:       }
│   21:   }
│ 
│ Key expression is required when building an object.
╵
╷
│ Error: Invalid 'for' expression
│ 
│   on routes.tf line 17, in resource "aws_route" "vpc_meta_route":
│   15:   for_each = {
│   16:     for route in local.routes :
│   17:       for cidr in route.cidr_blocks : "${route}-${cidr}" => {
│ 
│ Extra characters after the end of the 'for' expression.
╵
FAIL

Значит, каждый из идентификаторов таблицы маршрутов должен содержать все блоки CIDR? Или он должен сопоставлять 1:1, то есть один блок CIDR с одним идентификатором таблицы маршрутов?

Marko E 21.06.2024 12:48

Это должен быть один блок CIDR на маршрут. Примерroute_private-1:"10.1.0.0/16",route_private-2:"10.2.0.0/16, ...

João Amaro 21.06.2024 14:20
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
54
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вам не хватает ключевого выражения в вашем for выражении.

Когда вы создаете объект, синтаксис требует: key => value

Например: {for s in var.list : s => upper(s)}

Может быть, вы хотите вместо этого создать массив? Если да, измените окружающие скобки.

for_each = [
  for route in local.routes :
    for cidr in route.cidr_blocks : "${route}-${cidr}" => {
      route_table_id         = route.route_table_ids
      destination_cidr_block = cidr
    }
]

Или добавьте значение ключа

for_each = {
  for route in local.routes : route =>
    for cidr in route.cidr_blocks : "${route}-${cidr}" => {
      route_table_id         = route.route_table_ids
      destination_cidr_block = cidr
    }
}

Оба возвращают исключение во втором выражении for: «Дополнительные символы после конца выражения for». Может ли это быть так, как я объявляю местных жителей?

João Amaro 21.06.2024 14:28
Ответ принят как подходящий

В итоге я поменял его на это, и это сработало нормально.

locals {
  route_table_ids = concat(module.vpc.private_route_table_ids, module.vpc.public_route_table_ids)
  cidr_blocks     = ["10.1.0.0/16", "10.2.0.0/16", "10.5.0.0/16"]
}

resource "aws_route" "vpc_meta_route" {
  for_each = {
    for pair in setproduct(local.route_table_ids, local.cidr_blocks) :
    "${pair[0]}-${pair[1]}" => {
      route_table_id         = pair[0]
      destination_cidr_block = pair[1]
    }
  }

  route_table_id         = each.value.route_table_id
  destination_cidr_block = each.value.destination_cidr_block
  gateway_id             = module.vpc.vgw_id
}

Ключевое слово for должно всегда появляться после открывающей скобки [ или открывающей скобки {, в зависимости от того, собираетесь ли вы создать результат типа кортежа или результат типа объекта.

Это остается верным, когда вы используете выражение for как результат другого выражения, содержащего for; ваше выражение является синтаксической ошибкой, поскольку ключевое слово for следует сразу за двоеточием внешнего выражения for.

Поскольку ваше внутреннее выражение for включает в себя как результат ключа, так и результат значения (с использованием разделителя =>), я предполагаю, что вы хотели, чтобы внутреннее выражение for также генерировало объект, и в этом случае вы бы заключили его в фигурные скобки следующим образом:

  {
    for route in local.routes : {
      for cidr in route.cidr_blocks : "${route}-${cidr}" => {
        route_table_id         = route.route_table_ids
        destination_cidr_block = cidr
      }
    }
  }

Однако внешнее выражение for по-прежнему недопустимо, поскольку в нем используются фигурные скобки, но не используется символ => для указания имени и значения атрибута для каждого результирующего атрибута.

Поскольку вы используете это в for_each, я полагаю, вашей целью было построить плоскую карту объектов, а это значит, что вам нужен дополнительный шаг, чтобы превратить эту двухуровневую вложенную структуру в плоскую структуру. Есть несколько разных способов сделать это, но наиболее похожий на то, что вы уже пробовали, — использовать скобки [] для внешнего выражения — создание кортежа объектов с вложенными объектами — а затем отбрасывать внешний кортеж с помощью функция слияния для объединения всех элементов кортежа в один объект:

  for_each = merge([
    for route in local.routes : {
      for cidr in route.cidr_blocks : "${route}-${cidr}" => {
        route_table_id         = route.route_table_ids
        destination_cidr_block = cidr
      }
    }
  ]...)

Здесь также используется символ ..., чтобы использовать элементы кортежа в качестве переменных аргументов, поэтому это ведет себя так, как если бы вы передали каждый элемент кортежа в качестве отдельного аргумента в merge, который затем соответствует тому, что ожидает эта функция.

Есть несколько различных движущихся частей, работающих вместе, чтобы получить этот результат, поэтому может быть полезно сначала попробовать разные части искусственным образом в результате выходного значения, чтобы вы могли точно понять, что дает каждый из различных шагов. так что в будущем вы сможете комбинировать эти строительные блоки в разных комбинациях. В частности, я предлагаю вам понаблюдать за результатом без merge, чтобы понять, что именно делает этот шаг слияния.

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