Терраформированное гнездо для петли

#amazon-web-services #for-loop #foreach #terraform #each

Вопрос:

Я немного борюсь здесь и задаюсь вопросом, возможно ли это вообще. У меня есть декальцинированный vars, как показано ниже:

 variable "subnets" {
  type = list(object({
    name = string
    cidr_block = string
  }))
  default = [
    {
      name = private
      cidr_block = 10.0.0.1/24
    },
    {
      name = public
      cidr_block = 10.0.0.2/24
    }
  ]
}
 

а затем я использую источник данных для запроса зон в текущем регионе

 data aws_availability_zones available {}
 

теперь я пытаюсь создать вышеуказанные подсети в каждой зоне az, и, похоже, я не могу объединить зоны с указанным выше var.

то, что я пытаюсь, это

 resource aws_suubnet subnet {
 for each  = {for idx,az.name in data.aws_availability_zones.available.names : idx => az.name}
 vpc_id    = var.vpc_id
 availability_zone = data.aws_availability_zones.available.names[each.key]
 cidr_block = (this is where I want to query my var.subnets but I don't seem to be able to do another for 
 here)
}
 

То, что я надеюсь получить, — это 6 подсетей, 3 частных и 3 общедоступных, по одной в каждой из зон. Был бы признателен за любую помощь здесь. Спасибо

Комментарии:

1. У вас их только два cidr_block ? Как вы хотите создать 6 подсетей? Вам не хватает 4 cidr_block .

Ответ №1:

Я думаю, что ваше намерение здесь состоит в том, чтобы динамически выбрать две доступные зоны доступности и объявить подсеть в каждой из них.

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

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


С этой оговоркой я все же хочу ответить на общий вопрос здесь, потому что эта общая идея «объединения» двух коллекций разной длины может возникнуть в других ситуациях, и поэтому знание шаблона для нее все равно может оказаться полезным, в том числе, если вы в конечном итоге решите сделать список зон доступности переменной, а не поиском источника данных.

 variable "subnets" {
  type = list(object({
    name       = string
    cidr_block = string
  }))
}

data "aws_availability_zones" "available" {
}

locals {
  # The availability zones are returned as an unordered
  # set, so we'll sort them to be explicit that we're
  # depending on one particular ordering.
  zone_names = sort(data.aws_availabililty_zones.available.names)

  subnets = tolist([
    for i, sn in var.subnets : {
      name       = sn.name
      cidr_block = sn.cidr_block
      zone       = element(local.zone_names, i)
    }
  ])
}
 

Последнее выражение в приведенном выше примере зависит от element функции, которая похожа на индексирование local.zone_names[i] , но вместо того, чтобы возвращать ошибку, если i она слишком велика, она вместо этого будет обтекаться и повторно выбирать те же элементы из списка зон снова.