A
Arun's Blog
← Back to all posts

Orchestrating Kubernetes on AWS with Terraform

EKSTerraformKubernetesContainers
TL;DR

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
Note

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.

Important

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.

Pro Tip

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

  1. Clone the repository with all module files
  2. Configure your AWS credentials
  3. Run terraform init to initialize providers
  4. Run terraform plan to preview changes
  5. Run terraform apply to create resources
  6. 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 pod for 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_on or 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.