Я пытался заставить эту работу работать, но просто не могу этого понять.
Можете ли вы помочь?
Он должен перебирать частный и общедоступный маршрут, а также 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 на маршрут. Примерroute_private-1:"10.1.0.0/16",route_private-2:"10.2.0.0/16, ...





Вам не хватает ключевого выражения в вашем 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». Может ли это быть так, как я объявляю местных жителей?
В итоге я поменял его на это, и это сработало нормально.
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, чтобы понять, что именно делает этот шаг слияния.
Значит, каждый из идентификаторов таблицы маршрутов должен содержать все блоки CIDR? Или он должен сопоставлять 1:1, то есть один блок CIDR с одним идентификатором таблицы маршрутов?