Back to VPC & Networking
Q5Question 5 of 8

Choosing VPC CIDR Ranges and Subnet Sizes Up Front

Key Concepts
  • Plan non-overlapping CIDRs centrally across the organization before any workload exists, because this decision is very hard to undo.
  • Reserve a large private range (e.g., 10.0.0.0/8) for the organization and hand out /16 blocks to individual VPCs from a central registry.
  • Size subnets for Availability Zones and tiers: three AZs with public, private-app, and database tiers means nine subnets per VPC.
  • EKS with VPC CNI gives each pod a real VPC IP, so EKS subnets need /20 or larger per AZ to avoid IP exhaustion.
  • Overlapping CIDRs permanently block inter-VPC communication through peering or Transit Gateway and require re-addressing to fix.
  • AWS IPAM (IP Address Manager) allocates and tracks CIDRs centrally, preventing overlaps by construction.
  • Leave gaps in the allocation for future VPCs and reserve space for secondary CIDRs in case a VPC grows.

Definition

Plan non-overlapping CIDRs centrally with room to grow, size subnets for AZs, growth, and EKS pod demand, because overlapping ranges permanently block inter-VPC communication.
  • CIDR (Classless Inter-Domain Routing) – The IP address range assigned to a VPC or subnet, such as 10.0.0.0/16, determining how many addresses are available.
  • Non-Overlapping CIDRs – A hard requirement for VPCs that communicate through peering or Transit Gateway; overlapping ranges make routing ambiguous.
  • AWS IPAM – IP Address Manager, an AWS service that allocates and tracks CIDRs centrally across the organization to prevent overlaps.
  • EKS Pod IP Demand – With the default VPC CNI, every Kubernetes pod gets a real VPC IP, consuming subnets much faster than plain EC2.
  • Secondary CIDR – An additional CIDR block you can add to a VPC later, useful when the original range runs out.

Choosing CIDRs is like assigning room-number ranges across all of National Bank of India's buildings before anyone moves in. If two buildings both number their rooms 101 to 200, you can never build a bridge between them, because room 150 would be ambiguous. So head office hands each building a unique block of numbers, leaves room for new floors, and gives busy buildings bigger blocks. One team picking numbers on its own, without the master plan, guarantees a clash later that no amount of local fixing can undo.

Understanding the Concepts

Why plan CIDR ranges before any workload exists?

CIDR planning is a one-way door. A subnet CIDR cannot be resized in place, and overlapping VPC CIDRs block peering and Transit Gateway connectivity permanently. Re-addressing a VPC means recreating subnets and migrating workloads, which in a running bank is enormously disruptive. So you plan before the first workload deploys.

JAVA
public class WhyPlanUpFront {
    // Subnet CIDR: cannot be resized in place
    // VPC CIDR overlap: blocks inter-VPC routing permanently
    // Fix for both: recreate subnets + migrate workloads
    // In a running bank: weeks of work, risk of outages
    // Plan once upfront → avoid years of pain
}

How do you allocate CIDRs across the organization?

Start with the big picture: how many VPCs and environments (production, staging, development) will exist, now and in a few years. Each needs its own non-overlapping block. A common pattern is to reserve a large private range such as 10.0.0.0/8 and hand out /16 blocks to individual VPCs, keeping a central registry so no two overlap.

TEXT
# Organization-wide CIDR allocation registry
Production      VPC : 10.0.0.0/16
Staging         VPC : 10.1.0.0/16
Development     VPC : 10.2.0.0/16
EKS Production  VPC : 10.10.0.0/16   (large /20 subnets for pod IPs)
Shared Services VPC : 10.20.0.0/16   (Transit Gateway hub)
(Reserved)          : 10.3.0.0/16 - 10.9.0.0/16  (future VPCs)

How do you size subnets within a VPC?

Within a VPC, size subnets for the Availability Zones and tiers. For three AZs with public, private-app, and private-database tiers, that is nine subnets, each a slice of the VPC CIDR. Leave headroom because you cannot resize a subnet in place.

TEXT
# Production VPC (10.0.0.0/16) subnet layout
Public subnets:        /24 each (251 usable IPs)
  10.0.1.0/24 (AZ-a)  ALB, NAT Gateway
  10.0.2.0/24 (AZ-b)  ALB, NAT Gateway
  10.0.3.0/24 (AZ-c)  ALB, NAT Gateway

Private app subnets:   /22 each (1019 usable IPs)
  10.0.16.0/22 (AZ-a)  Application servers
  10.0.20.0/22 (AZ-b)  Application servers
  10.0.24.0/22 (AZ-c)  Application servers

Private DB subnets:    /24 each (251 usable IPs)
  10.0.32.0/24 (AZ-a)  RDS primary
  10.0.33.0/24 (AZ-b)  RDS standby
  10.0.34.0/24 (AZ-c)  RDS replica

Why does EKS need larger subnets?

With the default VPC CNI, every Kubernetes pod gets a real VPC IP address. A cluster running thousands of pods can exhaust a subnet that would be fine for plain EC2. You must size EKS subnets much larger, often a /20 or bigger per AZ, or plan for a secondary CIDR or prefix delegation.

DIAGRAM
# EKS IP demand calculation
EC2 instance:  1 IP per instance
EKS pod:       1 IP per pod + ENI IPs per instance

Example: 50 m5.large instances, each running 30 pods
EC2 only: 50 IPs needed
EKS pods: 50 * 30 = 1,500 IPs needed (30x more!)

Subnet /24 = 251 usable IPs → NOT ENOUGH for EKS
Subnet /20 = 4,091 usable IPs → sufficient for growth
BASH
# Create large EKS subnets
aws ec2 create-subnet --vpc-id vpc-eks --cidr-block 10.10.0.0/20 --availability-zone ap-south-1a
aws ec2 create-subnet --vpc-id vpc-eks --cidr-block 10.10.16.0/20 --availability-zone ap-south-1b
aws ec2 create-subnet --vpc-id vpc-eks --cidr-block 10.10.32.0/20 --availability-zone ap-south-1c

What happens when CIDRs overlap?

Overlapping CIDRs make inter-VPC routing impossible. If both VPCs use 10.0.0.0/16, a route to 10.0.5.9 is ambiguous. Peering creation fails, and Transit Gateway routing breaks. The fix requires re-addressing a VPC: recreating subnets, migrating instances, updating DNS, and retesting everything.

JAVA
public class OverlapConsequences {
    // Team A picks 10.0.0.0/16 for dev VPC
    // Team B picks 10.0.0.0/16 for staging VPC
    // Try to connect via Transit Gateway → FAILS
    // Fix: re-address one VPC
    //   1. Create new VPC with unique CIDR
    //   2. Recreate all subnets
    //   3. Migrate all instances and databases
    //   4. Update all DNS records
    //   5. Update all Security Group rules
    //   6. Test everything
    // In a running bank: weeks of disruptive work
}

What is AWS IPAM and how does it help?

AWS IPAM (IP Address Manager) allocates and tracks CIDRs centrally across the organization, preventing overlaps by construction. Teams request a block from the IPAM pool instead of choosing their own, and IPAM ensures no two allocations conflict.

BASH
# Create an IPAM pool for the organization
aws ec2 create-ipam-pool \
  --ipam-scope-id ipam-scope-0abc \
  --address-family ipv4 \
  --allocation-min-netmask-length 16 \
  --allocation-max-netmask-length 16

# Provision the top-level CIDR
aws ec2 provision-ipam-pool-cidr \
  --ipam-pool-id ipam-pool-0abc \
  --cidr 10.0.0.0/8

# Teams allocate from the pool – IPAM prevents overlaps
aws ec2 allocate-ipam-pool-cidr \
  --ipam-pool-id ipam-pool-0abc \
  --netmask-length 16
# Returns: 10.0.0.0/16 (or next available non-overlapping block)

What are common mistakes?

The first mistake is letting individual teams choose CIDRs without a central plan. Two teams independently picking 10.0.0.0/16 is guaranteed when no registry exists.

The second mistake is sizing subnets too small, especially for EKS. A /28 has 11 usable IPs and fills instantly with Kubernetes pods.

The third mistake is not leaving room for growth. You cannot resize a subnet, so under-sizing means creating a new one and migrating workloads.

DIAGRAM
# Common sizing mistakes
/28 (11 IPs)  → fills with 12 EKS pods, deployment blocked
/24 (251 IPs) → fine for EC2, too small for EKS
/20 (4,091 IPs) → right for EKS with room to grow
/16 (65,531 IPs) → VPC level, subdivide into subnets

What should a senior engineer know?

A senior engineer treats IP address management as an organization-wide architecture decision, not a per-VPC one. They use AWS IPAM to prevent overlaps by construction, leave gaps for future VPCs, reserve space for secondary CIDRs, and document the allocation in a central registry. They size EKS subnets for pod IP demand from the start, knowing that fixing IP exhaustion later requires subnet recreation.

They also know that secondary CIDRs can be added to a VPC later (up to 5 total), but the secondary range must also be non-overlapping, and workloads on the secondary CIDR may have routing limitations with some services.

BASH
# Add a secondary CIDR when the original runs out
aws ec2 associate-vpc-cidr-block \
  --vpc-id vpc-0abc \
  --cidr-block 100.64.0.0/16
# RFC 6598 shared address space – no overlap with RFC 1918
# Create new subnets in the secondary range for EKS pods

Visual Overview

DIAGRAM
┌──────── CIDR Planning: Organization-Wide ────────┐
│                                                    │
│  Organization Pool: 10.0.0.0/8                     │
│  Managed by AWS IPAM                               │
│                                                    │
│  ┌────────────────────────────────────────┐        │
│  │ Production VPC:     10.0.0.0/16        │        │
│  │   Public subnets:   10.0.1-3.0/24     │        │
│  │   App subnets:      10.0.16-28.0/22   │        │
│  │   DB subnets:       10.0.32-34.0/24   │        │
│  ├────────────────────────────────────────┤        │
│  │ Staging VPC:        10.1.0.0/16        │        │
│  ├────────────────────────────────────────┤        │
│  │ Development VPC:    10.2.0.0/16        │        │
│  ├────────────────────────────────────────┤        │
│  │ EKS Production:     10.10.0.0/16       │        │
│  │   Pod subnets:      10.10.0-32.0/20   │        │
│  │   (4,091 IPs per AZ for pod demand)    │        │
│  ├────────────────────────────────────────┤        │
│  │ (Reserved for future): 10.3-9.0.0/16   │       │
│  └────────────────────────────────────────┘        │
│                                                    │
│  Rule: NO OVERLAPS or peering/TGW breaks           │
│  Fix for overlap: re-address a live VPC (painful)  │
└────────────────────────────────────────────────────┘

Key Takeaway

Choosing VPC CIDR ranges and subnet sizes is a planning exercise I do before any workload exists, because the decisions are very hard to undo. I start from the big picture – how many VPCs and environments will exist now and over the next few years – and I reserve a large private range for the whole organization, typically carving out a /16 per VPC from 10.0.0.0/8, with a central registry so no two overlap. Inside each VPC I size subnets for the Availability Zones and tiers, and I leave headroom because a subnet CIDR cannot be resized in place.

The biggest surprise to plan for is EKS. With the default VPC CNI, every Kubernetes pod gets a real VPC IP address, so a cluster running thousands of pods can exhaust a subnet that would have been fine for plain EC2. I size EKS subnets much larger, often a /20 or bigger per Availability Zone, or I plan for a secondary CIDR or prefix delegation.

The hard rule that makes this an organization-wide decision is connectivity. VPCs that talk through peering or a Transit Gateway must have non-overlapping CIDRs, because overlapping ranges make routing ambiguous and cannot be fixed with routes. The fix requires re-addressing a VPC, recreating subnets, and migrating workloads, which in a running bank is enormously disruptive.

At National Bank of India this is exactly why we treat IP address management centrally. We use AWS IPAM to allocate and track every CIDR from one pool, which prevents overlaps by construction, we leave gaps for future VPCs, and we size EKS subnets far larger than our EC2 subnets because of pod IP demand.

Remember one sentence: Plan non-overlapping CIDRs centrally across the organization with room to grow, because overlapping ranges permanently block inter-VPC communication and re-addressing a live bank network is enormously disruptive.

---

Share
Use ← → arrow keys to navigate