DEV Community

Cover image for Automating EKS Deployment with Terraform: A Step-by-Step Guide
Gaurav Tayade
Gaurav Tayade

Posted on

2 1 1 1

Automating EKS Deployment with Terraform: A Step-by-Step Guide

Introduction

Managing Kubernetes clusters on AWS can be complex, but Terraform simplifies infrastructure provisioning. In this blog, I’ll walk you through how I automated the deployment of an EKS cluster with IAM roles, node groups, and an ALB controller using Terraform.


Why Terraform for EKS?

Terraform provides Infrastructure as Code (IaC), making infrastructure repeatable and scalable. By using Terraform to deploy EKS, you:

  • Avoid manual configurations
  • Ensure consistency across environments
  • Automate infrastructure creation and scaling

Project Overview

This Terraform script accomplishes the following:

  • Creates an IAM role for the EKS control plane
  • Deploys an EKS cluster
  • Sets up an IAM role for worker nodes
  • Configures an EKS node group with private subnets
  • Adds an SSH key pair for remote access
  • Deploys an AWS Load Balancer Controller

Project Structure

To keep the Terraform code modular, we will create a separate vars.tf file to store all the required variables.

Directory Structure:

terraform-eks/
│-- main.tf
│-- variables.tf
│-- outputs.tf
│-- terraform.tfvars
│-- alb-ing-iam_policy.json
│-- providers.tf
|-- alb-ingress.tf
**
Enter fullscreen mode Exit fullscreen mode

Terraform Script Breakdown

1. Create a Variables File (variables.tf)

variable "aws_region" {
  type        = string
  description = "AWS Region"
  default     = "us-east-1"
}

variable "vpc_id" {
   type        = string
   description = "AWS VPC Id"
   sensitive   = true
}

variable "aws_private_subnets" {
    type        = list(string)
    description = "List of Subnets"
    sensitive   = true
}

variable "cluster_version" {
  type        = number
  description = "EKS Cluster Version"
  default     = 1.31
}


Enter fullscreen mode Exit fullscreen mode

2. Define Terraform Variables File (terraform.tfvars)

aws_region = "us-east-1"
vpc_id = "vpc-************"
aws_private_subnets = aws_private_subnets = ["private-subnet-1", "private-subnet-1"]
cluster_version = 1.31

Enter fullscreen mode Exit fullscreen mode

3. Defining Local Variables in main.tf

locals {
  name = "eks-demo"
  common_tag = {
    Env = "Dev"
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Creating IAM Policy for ALB Ingress Controller

resource "aws_iam_policy" "alb_ingress_policy" {
  name        = "${local.name}-ALBEksControllerPolicy"
  description = "IAM policy for ALB Ingress Controller"
  policy      = file(var.alb_ingress_policy_file)
}
Enter fullscreen mode Exit fullscreen mode

5. Creating IAM Role for ALB Ingress Controller

resource "aws_iam_role" "alb_ingress_role" {
  name               = "${local.name}-ALBEksControllerRole"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          Service = "eks.amazonaws.com"
        }
        Action = "sts:AssumeRole"
      }
    ]
  })
}
Enter fullscreen mode Exit fullscreen mode

6. Attaching IAM Policy to Role

resource "aws_iam_role_policy_attachment" "alb_ingress_policy_attachment" {
  policy_arn = aws_iam_policy.alb_ingress_policy.arn
  role       = aws_iam_role.alb_ingress_role.name
  depends_on = [
    aws_iam_policy.alb_ingress_policy,
    aws_iam_role.alb_ingress_role
  ]
}
Enter fullscreen mode Exit fullscreen mode

7. Creating Kubernetes Service Account for ALB Controller

resource "kubernetes_service_account" "alb_ingress_sa" {
  metadata {
    name      = "alb-ingress-controller"
    namespace = "kube-system"
    annotations = {
      "eks.amazonaws.com/role-arn" = aws_iam_role.alb_ingress_role.arn
    }
  }
  depends_on = [ aws_iam_role_policy_attachment.alb_ingress_policy_attachment, aws_eks_cluster.eks_cluster ]
}
Enter fullscreen mode Exit fullscreen mode

8. Deploying AWS Load Balancer Controller with Helm

resource "helm_release" "alb_ingress_controller" {
  name       = "alb-ingress-controller"
  repository = "https://aws.github.io/eks-charts"
  chart      = "aws-load-balancer-controller"
  namespace  = "kube-system"
  set = [ 
    {
      name  = "clusterName"
      value = aws_eks_cluster.eks_cluster.name
    },
    {
      name  = "serviceAccount.create"
      value = "false"
    },
    {
      name  = "serviceAccount.name"
      value = kubernetes_service_account.alb_ingress_sa.metadata[0].name
    },
    {
      name  = "ingressClass"
      value = "alb"
    },
    {
      name  = "vpcID"
      value = var.vpc_id
    },
    {
      name  = "region"
      value = var.aws_region
    }
  ]
  depends_on = [ kubernetes_service_account.alb_ingress_sa ]
}
Enter fullscreen mode Exit fullscreen mode

Complete Deployment Flow

Clone the repository:

git clone https://github.com/gauravtayade11/terraform-eks-alb.git

Enter fullscreen mode Exit fullscreen mode

Initialize Terraform:

terraform init
Enter fullscreen mode Exit fullscreen mode

Validate the configuration:

terraform validate
Enter fullscreen mode Exit fullscreen mode

Apply Terraform to create resources:

terraform apply -auto-approve
Enter fullscreen mode Exit fullscreen mode

Verify the cluster:

aws eks --region us-east-1 update-kubeconfig --name eks-demo-cluster
kubectl get nodes
Enter fullscreen mode Exit fullscreen mode

Conclusion

With this Terraform script, we:

  • Created an EKS cluster
  • Configured IAM roles and node groups
  • Set up a scalable node group
  • Installed an AWS Load Balancer Controller

Using Terraform ensures repeatability, scalability, and automation. Feel free to try this setup and modify it to match your needs. 🚀

Check out the complete code on GitHub: GitHub Repository

Let me know in the comments if you have any questions or improvements! 👇


Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay