Home > Enterprise >  Filter out Subnet IDs based on sufficient capacity in availability zones in Terraform
Filter out Subnet IDs based on sufficient capacity in availability zones in Terraform

Time:02-03

I'm trying to deploy an EKS cluster and everything seems to be fine except for one!

The facade module looks like this:

module "eks" {
  source = "../../../../infrastructure_modules/eks"

  ## EKS ##
  create_eks      = var.create_eks
  cluster_version = var.cluster_version
  cluster_name    = local.cluster_name
  vpc_id          = data.aws_vpc.this.id
  subnets         = data.aws_subnet_ids.this.ids

  # note: either pass worker_groups or node_groups
  # this is for (EKSCTL API) unmanaged node group
  worker_groups = var.worker_groups

  # this is for (EKS API) managed node group
  node_groups = var.node_groups

  ## Common tag metadata ##
  env      = var.env
  app_name = var.app_name
  tags     = local.eks_tags
  region   = var.region
}

The VPC id is retrieved through the following block :

data "aws_vpc" "this" {
  tags = {
    Name = "tagName"
  }
}

Which then is used to retrieve the subnet_IDs as following:

data "aws_subnet_ids" "this" {
  vpc_id = data.aws_vpc.this.id
}

Nevertheless, deploying this results in error stating:

Error: error creating EKS Cluster (data-layer-eks): UnsupportedAvailabilityZoneException: Cannot create cluster 'data-layer-eks' because us-east-1e, the targeted availability zone, does not currently have sufficient capacity to support the cluster.

Which is a well known error, and anybody can come across this for even EC2s.

I could solve this by simply hardcoding the subnet value, but that's really undesirable and hardly maintainable.

So the question is, how can I filter out subnet_IDs based on availability zones that have sufficient capacity?

CodePudding user response:

First you need to collect the subnets with all of their attributes:

data "aws_subnets" "this" {
  filter {
    name   = "vpc-id"
    values = [data.aws_vpc.this.id]
  }
}

data "aws_subnet" "this" {
  for_each = toset(data.aws_subnets.this.ids)
  id       = each.value
}

data.aws_subnet.this is now a map(object) with all of the subnets and their attributes. You can now filter by availability zone accordingly:

subnets = [for subnet in data.aws_subnet.this : subnet.id if subnet.availability_zone != "us-east-1e"]

You can also filter by truthy conditionals if that condition is easier for you:

subnets = [for subnet in data.aws_subnet.this : subnet.id if contains(["us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d"], subnet.availability_zone)]

It depends on your personal use case.

  •  Tags:  
  • Related