Получение списка различных значений из карты

#loops #for-loop #foreach #terraform

Вопрос:

Я хотел бы создать шлюз NAT для каждой отдельной зоны доступности в terraform.Для этого мне нужно было бы получить список различных зон доступности.

 variable "public_subnets" {
 type = map(object({
   cidr = string
   az   = string
 }))
 description = "Public subnets for My VPC"
}
 

Подсеть

 public_subnets = {
 "a" = {
   cidr = "10.0.0.0/24"
   az   = "us-east-2a"
 },
 "b" = {
   cidr = "10.0.1.0/24"
   az   = "us-east-2b"
 }
}
 

Ресурсы будут определены следующим образом:

    resource "aws_subnet" "public-subnets" {
     for_each          = var.public_subnets
     vpc_id            = aws_vpc.main_vpc.id
     cidr_block        = each.value.cidr
     availability_zone = each.value.az
     map_public_ip_on_launch = true
     
     tags = {
       Name = "public-subnet-${each.value.cidr}-${each.value.az}"
     }
    }


resource "aws_eip" "ip-nats" {
  for_each = aws_subnet.public-subnets
  # EIP may require IGW to exist prior to association. 
  depends_on = [aws_internet_gateway.igw]
}
 

При создании каждого aws_nat_gateway из них мне нужно будет указать allocation_id и subnet_id . На типичном языке программирования я бы сделал следующее:

  1. Создайте эластичные IP-адреса для каждой общедоступной подсети и создайте карту / словарь с общедоступной подсетью в качестве ключа с эластичным IP-адресом в качестве значения
  2. Выполните цикл для этого словаря и создайте шлюз NAT.

Как мне добиться этого с помощью terraform

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

1. Вы не показали, как вы определили aws_subnet.public-subnets . Также какие «различные значения» в вашей карте? CIDRS?

2. @Marcin Добавил я aws_subnet.public-subnets . Под «различными значениями» я подразумеваю уникальные зоны доступности (AZ). В конечном счете, я хотел бы создать один шлюз nat для каждого AZ и назначить подсети шлюзам nat

Ответ №1:

aws_nat_gateway Эффективно ведет себя как сопряжение определенного эластичного IP-адреса «ID распределения» и определенного идентификатора подсети, и поэтому я предполагаю, что ваша цель здесь — создать одно такое сопряжение для каждой соответствующей пары экземпляров вашего aws_subnet.public-subnets и aws_eip.ip-nats ресурсов.

Поскольку эти шлюзы NAT будут взаимно однозначными при каждой записи var.public_subnets , вы можете просто использовать for_each эту карту еще раз, а затем сообщить Terraform, как собирать данные из соответствующих экземпляров других ресурсов:

 resource "aws_nat_gateway" "example" {
  for_each = var.public_subnets

  allocation_id = aws_eip.ip-nats[each.key]
  subnet_id     = aws_subnet.public-subnets[each.key]
  # ...
}
 

Также может быть допустимо использовать for_each цепочку из одного из других ресурсов, как вы делали для цепочки aws_eip.ip-nats из aws_subnet.public-subnets , но я решил просто использовать исходную коллекцию здесь, потому что мы можем одновременно подключаться только к одному другому ресурсу, и ни один ресурс здесь не кажется явно «более связанным» со шлюзом NAT, чем другой: каждый шлюз NAT происходит от одного экземпляра каждого из них одинаково.