Subnetcalculator

EKS Multi-AZ Subnet Splitter

Split a VPC CIDR into public, private, and pod subnets across every availability zone your EKS cluster spans.

EKS Multi-AZ Subnet Splitter

Subnet types needed

Subnets planned
6
VPC utilization
75%

Subnet layout

CIDR Type AZ Usable IPs
10.0.0.0/19 Public AZ 1 8,187
10.0.32.0/19 Public AZ 2 8,187
10.0.64.0/19 Public AZ 3 8,187
10.0.96.0/19 Private/Node AZ 1 8,187
10.0.128.0/19 Private/Node AZ 2 8,187
10.0.160.0/19 Private/Node AZ 3 8,187

Copy-paste config

resource "aws_subnet" "public_1" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.0.0/19"
  availability_zone       = data.aws_availability_zones.available.names[0]
  map_public_ip_on_launch = true

  tags = {
    Name = "public-1"
    Tier = "public"
  }
}

resource "aws_subnet" "public_2" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.32.0/19"
  availability_zone       = data.aws_availability_zones.available.names[1]
  map_public_ip_on_launch = true

  tags = {
    Name = "public-2"
    Tier = "public"
  }
}

resource "aws_subnet" "public_3" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.64.0/19"
  availability_zone       = data.aws_availability_zones.available.names[2]
  map_public_ip_on_launch = true

  tags = {
    Name = "public-3"
    Tier = "public"
  }
}

resource "aws_subnet" "private_1" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.96.0/19"
  availability_zone       = data.aws_availability_zones.available.names[0]
  map_public_ip_on_launch = false

  tags = {
    Name = "private-1"
    Tier = "private"
  }
}

resource "aws_subnet" "private_2" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.128.0/19"
  availability_zone       = data.aws_availability_zones.available.names[1]
  map_public_ip_on_launch = false

  tags = {
    Name = "private-2"
    Tier = "private"
  }
}

resource "aws_subnet" "private_3" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.160.0/19"
  availability_zone       = data.aws_availability_zones.available.names[2]
  map_public_ip_on_launch = false

  tags = {
    Name = "private-3"
    Tier = "private"
  }
}

Managing VPC layouts across multiple clusters?

💾 Join the SubnetVault waitlist

Also see: AWS subnet calculator · EKS max pods per node calculator · Kubernetes pod & service CIDR calculator

Why AZ spread is a VPC design decision, not a Kubernetes setting

Kubernetes concepts like pod anti-affinity and topology spread constraints assume the underlying infrastructure already exists in multiple failure domains — they schedule around AZs, they don't create them. That infrastructure layer is the VPC: subnets are AZ-scoped resources in AWS, so "spread the cluster across 3 AZs" really means "create node, pod, and load-balancer subnets in each of 3 AZs and let the EKS control plane and node groups reference all of them." Get the VPC layout wrong — too few AZs, or subnets sized without headroom — and no amount of Kubernetes-level scheduling configuration fixes it.

This is a different question from how big the cluster-wide pod or service CIDR should be (covered by the pod & service CIDR calculator) or how many pods a single node can run (covered by the max-pods calculator). This tool answers the layout question underneath both: given a VPC CIDR, how does it get divided into actual AZ-scoped subnets that Terraform or eksctl can create.

NAT gateway placement and the private-subnet sizing mistake

The most common undersizing mistake is treating public and private subnets as the same size by default. Public subnets in an EKS VPC typically only need IPs for load balancer ENIs and NAT gateway interfaces — a handful per AZ. Private/node subnets need an IP for every worker node, and — without custom networking — an IP for every pod on every node in that AZ. Splitting a VPC evenly across tiers routinely leaves the private tier undersized relative to actual growth, which surfaces as a VPC rebuild months later rather than a five-minute config change now.

NAT gateway placement compounds this: keeping one NAT gateway per AZ, in that AZ's own public subnet, with the matching private subnet's route table pointed at it, keeps each AZ's egress path self-contained. A single shared NAT gateway saves on hourly cost but means every other AZ's outbound traffic crosses an AZ boundary — added latency, added inter-AZ data transfer charges, and a single choke point that defeats the reason for spreading across AZs in the first place.

EKS Multi-AZ Subnet FAQ

How many AZs should a production EKS cluster span?

Three is the practical floor for production. EKS's own control plane requires subnets in at least two AZs, but two-AZ worker capacity means losing one AZ removes half your capacity at once — and Kubernetes' default pod anti-affinity and topology spread assumptions work more cleanly across an odd number. Three AZs is also the ceiling in several regions (some AWS regions only have three availability zones total), so it's the number most reference architectures converge on rather than an arbitrary recommendation.

Do pod subnets need to be per-AZ?

Yes, if you're using custom networking (secondary CIDR pod subnets) at all — each pod subnet is associated with a specific AZ via its ENIConfig, and a node only draws pod IPs from the pod subnet matching its own AZ. A pod subnet that doesn't exist in a given AZ simply means nodes launched there can't get pod IPs through custom networking. This is different from the pod CIDR calculator's cluster-wide sizing question — this tool is about how that per-AZ pod address space maps onto your actual VPC layout.

Why not just make every subnet the same size?

Public subnets typically only host load balancers and NAT gateway ENIs — a handful of IPs per AZ. Private/node subnets host every worker node, every node's pods (without custom networking), and scale with cluster size. Sizing both identically either wastes address space on the public tier or, more commonly, undersizes the private tier and forces a VPC rebuild once node count grows. The weighted strategy in this calculator gives private subnets a larger share of the VPC's address space by default for exactly this reason.

Where should NAT gateways go in a multi-AZ layout?

One NAT gateway per AZ, placed in that AZ's public subnet, with private-subnet route tables in the same AZ pointing to it. A single shared NAT gateway is cheaper but makes every other AZ's egress traffic cross an AZ boundary — extra latency and inter-AZ data transfer cost, and a single point of failure for the whole cluster's outbound traffic. Per-AZ NAT gateways cost more (one per AZ) but keep each AZ's failure domain self-contained, which is the point of spreading across AZs in the first place.

More Network Tools

Free tools for network engineers — no signup, no rate-limit walls.