Home > Net >  Get a list of distinct values from map
Get a list of distinct values from map

Time:11-04

I would like to create a NAT gateway for each distinct availability zone in terraform.For that to happen i would need to get a list of distinct availability zones.

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

Subnet

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

The resources would be defined as follows:

   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]
}

When creating each aws_nat_gateway i would need to state the allocation_id and subnet_id. In a typical programming language i would do the following:

  1. Create elastic ips for each public subnet and create a map / dictionary with public subnet as key with the elastic ip as value
  2. Loop for that dictionary and create the NAT gateway.

How do i achieve this with terraform

CodePudding user response:

An aws_nat_gateway effectively behaves as a pairing of a particular Elastic IP "allocation ID" and a particular subnet ID, and so I assume your goal here is to create one such pairing for each corresponding pair of instances of your aws_subnet.public-subnets and aws_eip.ip-nats resources.

Since these NAT gateways will be one-to-one with each entry in var.public_subnets, you can just use for_each with that map one more time and then tell Terraform how to gather the data from the relevant instances of the other resources:

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]
  # ...
}

It could also be valid to use for_each chaining from one of the other resources as you did to chain aws_eip.ip-nats from aws_subnet.public-subnets, but I chose to just use the original collection here because we can only chain from one other resource at a time and neither resource here seems obviously "more connected" to the NAT gateway than the other: each NAT gateway descends from one instance of each of them equally.

  • Related