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
**
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
}
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
3. Defining Local Variables in main.tf
locals {
name = "eks-demo"
common_tag = {
Env = "Dev"
}
}
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)
}
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"
}
]
})
}
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
]
}
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 ]
}
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 ]
}
Complete Deployment Flow
Clone the repository:
git clone https://github.com/gauravtayade11/terraform-eks-alb.git
Initialize Terraform:
terraform init
Validate the configuration:
terraform validate
Apply Terraform to create resources:
terraform apply -auto-approve
Verify the cluster:
aws eks --region us-east-1 update-kubeconfig --name eks-demo-cluster
kubectl get nodes
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! 👇
Top comments (0)