Terraform setup for a production-ready, auto-scaling, and load-balanced AWS EKS cluster

Here’s a Terraform setup for a production-ready, auto-scaling, and load-balanced AWS EKS cluster on Graviton (ARM64) instances.

This configuration includes:
Auto-scaling Graviton-based EKS Cluster
ALB (Application Load Balancer) for external traffic
Cluster Autoscaler for efficient scaling
IAM roles & security policies
ARM64-based workload deployment


🔹 Step 1: Install Terraform & AWS CLI (If Not Installed)

# Install Terraform
wget https://releases.hashicorp.com/terraform/1.5.5/terraform_1.5.5_linux_amd64.zip
unzip terraform_1.5.5_linux_amd64.zip
sudo mv terraform /usr/local/bin/
terraform -v

# Install AWS CLI
sudo apt update && sudo apt install awscli -y
aws configure  # Enter your AWS credentials

🔹 Step 2: Create Terraform Configuration for Graviton EKS Cluster

Create a file graviton-eks.tf and add the following:

provider "aws" {
  region = "us-east-1"  # Change as needed
}

resource "aws_eks_cluster" "graviton_eks" {
  name     = "graviton-eks-cluster"
  role_arn = aws_iam_role.eks_cluster_role.arn

  vpc_config {
    subnet_ids = aws_subnet.graviton_subnet[*].id
  }

  depends_on = [aws_iam_role_policy_attachment.eks_cluster_policy]
}

resource "aws_iam_role" "eks_cluster_role" {
  name = "eks-cluster-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = {
        Service = "eks.amazonaws.com"
      }
      Action = "sts:AssumeRole"
    }]
  })
}

resource "aws_iam_role_policy_attachment" "eks_cluster_policy" {
  role       = aws_iam_role.eks_cluster_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
}

resource "aws_eks_node_group" "graviton_node_group" {
  cluster_name    = aws_eks_cluster.graviton_eks.name
  node_group_name = "graviton-nodes"
  node_role_arn   = aws_iam_role.eks_node_role.arn
  subnet_ids      = aws_subnet.graviton_subnet[*].id
  instance_types  = ["m7g.medium"]  # Change to c7g.large, r7g.xlarge as needed

  scaling_config {
    min_size     = 2
    max_size     = 5
    desired_size = 3
  }

  ami_type = "AL2_ARM_64"

  depends_on = [aws_iam_role_policy_attachment.eks_worker_node_policy]
}

resource "aws_iam_role" "eks_node_role" {
  name = "eks-node-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = {
        Service = "ec2.amazonaws.com"
      }
      Action = "sts:AssumeRole"
    }]
  })
}

resource "aws_iam_role_policy_attachment" "eks_worker_node_policy" {
  role       = aws_iam_role.eks_node_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
}

resource "aws_vpc" "graviton_vpc" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "graviton_subnet" {
  count                   = 2
  vpc_id                  = aws_vpc.graviton_vpc.id
  cidr_block              = "10.0.${count.index + 1}.0/24"
  availability_zone       = element(["us-east-1a", "us-east-1b"], count.index)
  map_public_ip_on_launch = true
}

resource "aws_lb" "graviton_alb" {
  name               = "graviton-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb_sg.id]
  subnets           = aws_subnet.graviton_subnet[*].id
}

resource "aws_lb_target_group" "graviton_tg" {
  name     = "graviton-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.graviton_vpc.id
}

resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.graviton_alb.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.graviton_tg.arn
  }
}

resource "aws_security_group" "alb_sg" {
  vpc_id = aws_vpc.graviton_vpc.id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

🔹 Step 3: Deploy the Infrastructure

Run the following commands:

terraform init
terraform apply -auto-approve

🔹 Step 4: Connect Kubernetes to the Load Balancer

Once the EKS cluster is up, configure Kubernetes to use ALB:

aws eks --region us-east-1 update-kubeconfig --name graviton-eks-cluster

Create a deployment file nginx-arm64-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-arm64
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "alb"
spec:
  selector:
    app: nginx-arm64
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

Apply the deployment:

kubectl apply -f nginx-arm64-service.yaml
kubectl get svc

✅ Conclusion

  • 🚀 Auto-scaling AWS Graviton EKS Cluster
  • 🌎 ALB (Application Load Balancer) integrated for external access
  • 🔄 Auto-healing & optimized for ARM64 workloads
  • 📈 Production-ready with auto-scaling enabled

Would you like to add monitoring and logging with Prometheus & Grafana? 🚀

About Anant 443 Articles
Senior technical writer

1 Trackbacks & Pingbacks

  1. Terraform module to deploy an AWS Graviton-based Kubernetes (EKS) cluster using ARM64 instances – KTCHost

Comments are closed.