⚡ ~/naveed Labs
⚡ Portfolio Home ✍️ Engineering Blog Deep Dives 🎯 Interview Hub 1,000+ Scenarios ☸️ Kubernetes Mastery Hub 24 Modules 🎮 DevOps Arcade & Quizzes Subnet Blitz ⚡ 🗺️ DevOps Roadmaps PDFs & Guides 🤖 Morpheus Analysis AI Quant ↗ 🛠️ Developer Tools Utilities 🧪 Labs & Experiments 📄 Interactive CV & Certs 🔗 All Links & Socials ⚡ Join The Dispatch (Weekly SRE Newsletter) →
⚡ DEVOPS LAB RUNBOOKS
AWS EKS Terraform IaC Karpenter v1 VPC CNI

Deploy Kubernetes on AWS with Terraform & EKS: Production Hands-On Runbook

Author: Naveed Ahmed • Updated: October 09, 2026 • Execution Time: ~15 mins
Looking for the complete architectural deep dive?
Read the comprehensive guide explaining EKS decision matrices, Pod Identity theory, cost models, and failure modes on the main engineering blog.
Read Architectural Blog Post →
1

Prerequisites & Environment Setup

Verify your local workstation has the required CLI binaries configured with authenticated AWS credentials:

# 1. Verify AWS Identity and Permissions
aws sts get-caller-identity

# 2. Verify Terraform / OpenTofu (>= 1.6.0)
terraform -version

# 3. Verify kubectl and helm
kubectl version --client --output=yaml
helm version --short
2

Multi-AZ VPC Provisioning (vpc.tf)

Deploy a 3-tier VPC with public subnets for load balancers and private subnets for EKS worker nodes. Ensure required Kubernetes ELB discovery tags are present:

# vpc.tf
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.8"

  name = "production-k8s-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["us-east-1a", "us-east-1b", "us-east-1c"]
  private_subnets = ["10.0.32.0/19", "10.0.64.0/19", "10.0.96.0/19"]
  public_subnets  = ["10.0.0.0/22", "10.0.4.0/22", "10.0.8.0/22"]

  enable_nat_gateway   = true
  single_nat_gateway   = false
  enable_dns_hostnames = true
  enable_dns_support   = true

  public_subnet_tags = {
    "kubernetes.io/role/elb" = "1"
  }

  private_subnet_tags = {
    "kubernetes.io/role/internal-elb" = "1"
    "karpenter.sh/discovery"          = "production-k8s-cluster"
  }
}
3

EKS Cluster & VPC CNI Prefix Delegation (cluster.tf)

Provision the Amazon EKS cluster with VPC CNI prefix delegation enabled to eliminate subnet IP exhaustion:

# cluster.tf
module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.10"

  cluster_name    = "production-k8s-cluster"
  cluster_version = "1.32"

  cluster_endpoint_public_access       = true
  cluster_endpoint_public_access_cidrs = ["YOUR_OFFICE_IP/32"]
  cluster_endpoint_private_access      = true

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  cluster_addons = {
    coredns = { most_recent = true }
    kube-proxy = { most_recent = true }
    eks-pod-identity-agent = { most_recent = true }
    vpc-cni = {
      most_recent    = true
      before_compute = true
      configuration_values = jsonencode({
        env = {
          ENABLE_PREFIX_DELEGATION = "true"
          WARM_PREFIX_TARGET       = "1"
        }
      })
    }
  }

  # Dedicated system node group for CoreDNS & Karpenter
  eks_managed_node_groups = {
    system = {
      name           = "system-nodes"
      instance_types = ["m6i.large"]
      min_size       = 2
      max_size       = 3
      desired_size   = 2

      labels = { role = "system" }
    }
  }
}
4

Deploy & Connect to the EKS Cluster

Apply the Terraform blueprint and generate your local kubeconfig:

# Initialize and provision infrastructure
terraform init
terraform apply -auto-approve

# Update local kubeconfig
aws eks update-kubeconfig --region us-east-1 --name production-k8s-cluster

# Verify control plane and nodes
kubectl get nodes -o wide
kubectl get pods -n kube-system
5

Configure Karpenter v1 Dynamic Autoscaling

Deploy Karpenter v1 to eliminate slow Auto Scaling Groups and achieve sub-minute just-in-time compute provisioning:

# karpenter-nodepool.yaml
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: default
spec:
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: "karpenter.k8s.aws/instance-category"
          operator: In
          values: ["c", "m", "r"]
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["spot", "on-demand"]
        - key: "kubernetes.io/arch"
          operator: In
          values: ["amd64", "arm64"]
  disruption:
    consolidationPolicy: WhenEmptyOrUnderutilized
    consolidateAfter: 1m
---
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: default
spec:
  amiFamily: AL2023
  role: "KarpenterNodeRole-production-k8s-cluster"
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: "production-k8s-cluster"
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: "production-k8s-cluster"
kubectl apply -f karpenter-nodepool.yaml
6

Verification: Workload Scaling & Prefix Validation

Deploy a test workload to observe Karpenter instant node provisioning and verify that pods receive prefix-delegated IPs:

# Deploy a test microservice with 25 replicas
kubectl create deployment test-scaling --image=nginx:alpine --replicas=25

# Watch Karpenter provision new nodes dynamically
kubectl get pods -o wide -w

# Check allocated pod IPs and node capacity
kubectl describe nodes -l role!=system | grep -i "pods:"
7

Teardown & Infrastructure Destruction

When you finish your validation testing, destroy all provisioned cloud resources to prevent ongoing AWS billing:

# 1. Delete test workloads and Karpenter nodes
kubectl delete deployment test-scaling
kubectl delete -f karpenter-nodepool.yaml

# 2. Destroy EKS and VPC resources
terraform destroy -auto-approve
Prepare for SRE & Cloud Architect Interviews:
How would you upgrade this cluster across minor versions without application downtime? Study the live interview question:
Zero-Downtime EKS Upgrade Scenario →