#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 подсетей? Вам не хватает 4cidr_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
она слишком велика, она вместо этого будет обтекаться и повторно выбирать те же элементы из списка зон снова.