Production-ready AWS EKS infrastructure boilerplate using Terraform. Deploy a complete Kubernetes cluster with a single terraform apply.
- EKS Cluster: Kubernetes 1.34 with managed node groups
- VPC: Multi-AZ VPC with public/private subnets
- EKS Addons: CoreDNS, kube-proxy, vpc-cni, aws-ebs-csi-driver
- Metrics Server: Pre-installed for HPA/VPA support
- ALB Ingress Controller: AWS Load Balancer Controller with IRSA
- Security: IMDSv2 enforcement, EBS encryption, VPC Flow Logs
- Remote State: S3 + DynamoDB backend support
┌─────────────────────────────────────────────────────────────────┐
│ AWS Region │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ VPC │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ Public Subnet │ │ Public Subnet │ │ │
│ │ │ (AZ-a) │ │ (AZ-b) │ │ │
│ │ │ NAT GW │ │ │ │ │
│ │ └─────────────────┘ └─────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ Private Subnet │ │ Private Subnet │ │ │
│ │ │ (AZ-a) │ │ (AZ-b) │ │ │
│ │ │ ┌───────────┐ │ │ ┌───────────┐ │ │ │
│ │ │ │EKS Node │ │ │ │EKS Node │ │ │ │
│ │ │ │(c5.xlarge)│ │ │ │(c5.xlarge)│ │ │ │
│ │ │ └───────────┘ │ │ └───────────┘ │ │ │
│ │ └─────────────────┘ └─────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ EKS Cluster │ │ │
│ │ │ • Metrics Server │ │ │
│ │ │ • AWS Load Balancer Controller (IRSA) │ │ │
│ │ │ • CoreDNS, kube-proxy, vpc-cni, ebs-csi-driver │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
- Terraform >= 1.5.0
- AWS CLI configured with appropriate credentials
- kubectl (optional, for cluster access)
cd assets/terraform_backend
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars with your values
terraform init
terraform applycd src
cp terraform.tfvars.example terraform.tfvars
cp backend.tf.example backend.tf
# Edit terraform.tfvars and backend.tf with your values
terraform init
# First deployment requires two-step apply (EKS module v21.x limitation)
terraform plan -target=module.vpc
terraform apply -target=module.vpc -auto-approve
terraform plan
terraform apply -auto-approveNote: The two-step deployment is required only for the first
terraform apply. Subsequent applies work normally. This is due to EKS module v21.x's internal data source dependencies.
aws eks update-kubeconfig --region ap-northeast-2 --name <cluster-name>.
├── assets/
│ └── terraform_backend/ # S3 + DynamoDB backend setup
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ ├── versions.tf
│ └── README.md
├── src/
│ ├── main.tf # Main orchestration
│ ├── variables.tf # Input variables
│ ├── outputs.tf # Output values
│ ├── locals.tf # Local values
│ ├── providers.tf # Provider configuration
│ ├── versions.tf # Version constraints
│ ├── backend.tf.example # Backend configuration template
│ ├── terraform.tfvars.example
│ ├── modules/
│ │ ├── vpc/ # VPC module
│ │ ├── eks/ # EKS module
│ │ └── addons/ # Kubernetes addons (metrics-server, alb-controller)
│ └── helm_values/ # Helm chart values
│ ├── metrics-server.yaml
│ └── aws-load-balancer-controller.yaml
├── examples/
│ └── hello-world/ # Example deployment
├── scripts/ # Deployment/cleanup scripts
│ ├── deploy-example.sh
│ └── cleanup-example.sh
└── README.md
| Variable | Description | Default |
|---|---|---|
project_name |
Project name for resource naming | - |
environment |
Environment name | dev |
region |
AWS region | ap-northeast-2 |
| Variable | Description | Default |
|---|---|---|
kubernetes_version |
Kubernetes version | 1.34 |
vpc_cidr |
VPC CIDR block | 10.0.0.0/16 |
availability_zones_count |
Number of AZs | 2 |
single_nat_gateway |
Use single NAT GW | true |
Note: Node group settings (instance type, size, etc.) are hardcoded in
src/modules/eks/main.tffor simplicity. Modify directly if needed.
See src/variables.tf for full list of configurable options.
| Module/Provider | Version |
|---|---|
| terraform | >= 1.5.0 |
| hashicorp/aws | ~> 6.0 |
| hashicorp/kubernetes | ~> 2.38 |
| hashicorp/helm | ~> 3.1 |
| terraform-aws-modules/vpc/aws | 6.5.1 |
| terraform-aws-modules/eks/aws | 21.10.1 |
| terraform-aws-modules/iam/aws | 6.2.3 |
| metrics-server (Helm) | 3.13.0 |
| aws-load-balancer-controller (Helm) | 1.16.0 |
| Output | Description |
|---|---|
cluster_name |
EKS cluster name |
cluster_endpoint |
EKS API endpoint |
configure_kubectl |
Command to configure kubectl |
vpc_id |
VPC ID |
alb_controller_role_arn |
ALB Controller IAM role ARN |
Deploy and test a sample application with ALB Ingress:
# Deploy and test (includes ALB provisioning wait)
./scripts/deploy-example.sh
# Cleanup
./scripts/cleanup-example.shOr manually:
kubectl apply -f examples/hello-world/- IMDSv2 Required: Instance metadata service v2 enforced on all nodes
- EBS Encryption: Node volumes encrypted at rest
- VPC Flow Logs: Network traffic logging enabled
- IRSA: IAM roles for service accounts (no static credentials)
- Private Nodes: Worker nodes in private subnets only
# Remove EKS infrastructure
cd src
terraform destroy
# Remove backend (optional)
cd assets/terraform_backend
terraform destroyMIT License