Orchestrating Kubernetes on AWS with Terraform
Deploy AWS EKS with Terraform using modules for VPC, EKS cluster, ALB controller, and a demo NGINX application. The setup includes managed node groups, AWS Load Balancer Controller via Helm, and Kubernetes resources (namespace, deployment, service, ingress) all defined in Terraform.
Introduction
In today's fast-paced digital landscape, businesses constantly seek innovative solutions to streamline operations, improve scalability, and ensure application resilience. Amazon Web Services (AWS) Elastic Kubernetes Service (EKS) provides a managed container service that allows you to run Kubernetes on AWS without installing and operating your own Kubernetes control plane.
AWS EKS Overview
AWS EKS is a managed service that makes it easier to use Kubernetes on AWS. Kubernetes, an open-source system for automating deployment, scaling, and management of containerized applications, is at the heart of modern development. EKS abstracts away the complexity of setting up a Kubernetes cluster from scratch.
Features and Benefits
- Fully Managed Control Plane - AWS handles setup, scalability, and availability of the API server and etcd
- AWS Service Integration - Deep integration with ELB, VPC, IAM, and more
- Scalability and Reliability - Auto-scales across multiple AZs with EC2 Auto Scaling Groups
- Security - IAM authentication, VPC network isolation, encryption at rest and in transit
- Hybrid Cloud - Clusters can span AWS and on-premises environments
This guide uses Terraform modules for a repeatable, infrastructure-as-code approach to EKS deployment. All code is modular and can be customized for your needs.
Terraform Modules
VPC Module
Creates the network environment with public and private subnets across two AZs, NAT gateways, and required Kubernetes tags.
The subnet tags (kubernetes.io/role/elb and kubernetes.io/role/internal-elb) are mandatory for the AWS Load Balancer Controller to discover subnets.
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.5.3"
name = "eks-vpc"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = 1
}
}
EKS Cluster Module
Creates the EKS cluster with managed node groups (blue and green), essential add-ons, and outputs needed for application deployment.
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "19.21.0"
cluster_version = "1.29"
cluster_name = "eks-cluster"
cluster_endpoint_public_access = true
cluster_addons = {
coredns = { most_recent = true }
kube-proxy = { most_recent = true }
vpc-cni = { most_recent = true }
aws-ebs-csi-driver = { most_recent = true }
}
vpc_id = var.vpc_id
subnet_ids = var.private_subnets
eks_managed_node_groups = {
blue = {
min_size = 1
max_size = 2
desired_size = 1
}
green = {
min_size = 1
max_size = 2
desired_size = 1
instance_types = ["t3.medium"]
capacity_type = "ON_DEMAND"
}
}
}
ALB Controller Module
Creates the IAM role, service account, and installs the AWS Load Balancer Controller via Helm.
The AWS Load Balancer Controller manages ALBs and NLBs for your Kubernetes services and ingresses. It's required for using AWS load balancers with EKS.
Demo Application
Deploys a complete application stack including:
- Kubernetes namespace
- IAM policy and role for the application
- Service account with IRSA (IAM Roles for Service Accounts)
- Deployment with NGINX containers
- NodePort service
- Ingress that creates an internet-facing ALB
Deployment
- Clone the repository with all module files
- Configure your AWS credentials
- Run
terraform initto initialize providers - Run
terraform planto preview changes - Run
terraform applyto create resources - The output includes the ALB DNS name - paste it in a browser to test
Troubleshooting
- ALB not created - Verify subnet tags are correct. Check ALB Controller logs with
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller. - Pods stuck in Pending - Check node group capacity. Run
kubectl describe podfor details. May need to increase node count or instance size. - Cannot connect to cluster - Update kubeconfig with
aws eks update-kubeconfig --name eks-cluster --region us-east-1. - Service account errors - Verify OIDC provider is created. Check IAM role trust policy includes the correct OIDC provider ARN.
- Terraform apply fails on Kubernetes resources - EKS cluster must be created first. Use
depends_onor apply in stages. - Ingress shows no address - Check ALB Controller is running. Verify ingress annotations are correct for your use case (internet-facing vs internal).
Conclusion
AWS EKS represents a significant leap forward in simplifying containerized application deployment at scale. By leveraging Kubernetes and AWS services together with Terraform, EKS provides a robust, scalable, and secure platform for modern application development. Whether you're an enterprise modernizing applications or a developer deploying scalable applications, AWS EKS offers a compelling solution.