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
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"
}
}
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" }
}
}
}
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
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
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:"
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