Имеют управляемые циклы в одном ресурсе terraform

#amazon-web-services #terraform #nested-loops #terraform-provider-aws

#amazon-веб-сервисы #terraform #вложенные циклы #terraform-provider-aws

Вопрос:

Я пытаюсь создать подсети на основе пользовательских данных, скажем, 4 (var.number_of_private_subnets). Я хочу, чтобы они находились в разных зонах доступности (Az). Я заметил, что Terraform иногда использует все доступные Az, а иногда и нет. поэтому по этой причине я не хочу оставлять его для terraform, чтобы выбрать AZ

 data aws_availability_zones "azs"{
  state = "available"

}
  
 resource "aws_subnet" "private_subnet" {
  count                = var.number_of_private_subnets
  cidr_block           = cidrsubnet(aws_vpc.main_vpc.cidr_block,8, count.index )
  vpc_id               = aws_vpc.main_vpc.id
  availability_zone    = data.aws_availability_zones.azs.names[count.index]


    tags   = {
      Name = "${var.env_name}-PrivateSubnet-${count.index 1}"
    }
}
  

Этот код завершается с ошибкой, если доступные az для конкретного aws_region равны 3, он попытается получить доступ к 4-му элементу списка, поскольку пользовательский ввод равен 4.

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

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

1. Конфигурация, которую вы показали здесь, опасна для будущего обслуживания: AWS может добавлять и удалять зоны доступности с течением времени, что может привести к появлению имен в разных count.index позициях, что затем заставит Terraform поверить, что вы намерены изменить зону доступности для существующей подсети, что является изменением, требующим удаления, а затем повторного создания подсети. Я думаю, что было бы безопаснее использовать for_each вместо count и создавать подсети во всех доступных AZS, даже если вы не собираетесь использовать их все сегодня, чтобы будущие дополнения не могли повлиять на существующие подсети.

Ответ №1:

Вы можете использовать оператор по модулю ( % ):

   availability_zone    = data.aws_availability_zones.azs.names[count.index % 3]
  

или еще лучше,

   availability_zone    = data.aws_availability_zones.azs.names[count.index % len(data.aws_availability_zones.azs.names)]
  

Кроме того, для тех, кто просто сразу переходит к ответам, обязательно прочтите комментарий Мартина Аткинса к этому вопросу.