Ravindra BagaleCourses & study guides मराठी

Chapter 78: DevOps Projects Part 8: Terraform Three-Tier EKS CI Drift CloudFormation Infracost

78.2 Project 56: EKS cluster with Terraform

Friends, EKS in Terraform means a cluster resource, node group, IAM roles, and add-ons. Today we write that HCL plan for ap-south-1 with private nodes and IRSA notes — apply only with budget approval.

What you will build in this project

  1. eks cluster HCL sketch.
  2. Managed node group sketch.
  3. IRSA notes.
  4. Upgrade order note.

1. Start from a real company story

At Zepto in Bengaluru, a console-built EKS drifted from the runbook. Nobody could recreate it after a region exercise.

Recreate took three nights. Rough cost: about ₹90 lakh in overtime and delayed launches.

Arjun moved the cluster definition into Terraform with pinned versions and IRSA.

Today we write that EKS Terraform plan.

cluster IAMcontrol planenode groupprivate subnetsIRSAservice accountsadd-onsvpc-cni
Picture 1: VPC → aws_eks_cluster → node group → IRSA apps

Ravindra Bagale's Tip

Students attach AdministratorAccess to the node role for speed. Use least privilege policies. Keep that habit.

2. Start and prepare

Step 1: Why EKS TF

Why: Recreate the cluster from code. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: echo why then cost gate. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 1: a1

Type this:

echo 'Terraform records cluster version, subnets, and IAM so recreate is possible'

You will see:

Terraform records cluster version, subnets, and IAM so recreate is possible

What it means: Why.

Example 2: a2

Type this:

mkdir -p /tmp/tf56 && printf '%s\n' 'COST: EKS control plane hourly + nodes + NAT + LB' 'Apply only with budget approval.' > /tmp/tf56/COST.txt && cat /tmp/tf56/COST.txt

You will see:

COST: EKS control plane hourly + nodes + NAT + LB

What it means: Cost gate.

Example 3: a3

Type this:

terraform version 2>/dev/null | head -1 || echo 'Terraform v1.9.0'

You will see:

Terraform v1.9.0

What it means: Tool ready.

Step 2: Provider folder

Why: ap-south-1 stack. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: provider.tf. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 4: b1

Type this:

printf '%s\n' 'terraform {' '  required_providers { aws = { source = "hashicorp/aws", version = "~> 5.0" } }' '}' 'provider "aws" { region = "ap-south-1" }' > /tmp/tf56/provider.tf && cat /tmp/tf56/provider.tf

You will see:

region = "ap-south-1"

What it means: Provider.

Example 5: b2

Type this:

printf '%s\n' '.terraform/' '*.tfstate*' > /tmp/tf56/.gitignore && cat /tmp/tf56/.gitignore

You will see:

.terraform/

What it means: Gitignore.

Example 6: b3

Type this:

echo 'Pass private subnet ids from the VPC module outputs'

You will see:

Pass private subnet ids from the VPC module outputs

What it means: Subnet tip.

Step 3: Cluster IAM

Why: Role the control plane assumes. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: aws_iam_role for eks. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 7: c1

Type this:

printf '%s\n' 'resource "aws_iam_role" "cluster" {' '  name = "shop-eks-cluster"' '  assume_role_policy = jsonencode({' '    Version = "2012-10-17"' '    Statement = [{' '      Action = "sts:AssumeRole"' '      Effect = "Allow"' '      Principal = { Service = "eks.amazonaws.com" }' '    }]' '  })' '}' > /tmp/tf56/iam-cluster.tf && grep eks.amazonaws.com /tmp/tf56/iam-cluster.tf

You will see:

Principal = { Service = "eks.amazonaws.com" }

What it means: Cluster trust policy.

Example 8: c2

Type this:

echo 'Attach AmazonEKSClusterPolicy to the cluster role'

You will see:

Attach AmazonEKSClusterPolicy to the cluster role

What it means: Policy tip.

Example 9: c3

Type this:

echo 'Never reuse the cluster role as a node role'

You will see:

Never reuse the cluster role as a node role

What it means: Separation tip.

3. Build the main pieces

Step 4: Cluster resource

Why: aws_eks_cluster sketch. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: printf cluster.tf. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 10: d1

Type this:

printf '%s\n' 'resource "aws_eks_cluster" "shop" {' '  name     = "shop-prod"' '  role_arn = aws_iam_role.cluster.arn' '  version  = "1.29"' '  vpc_config {' '    subnet_ids              = ["subnet-priv-a", "subnet-priv-b"]' '    endpoint_private_access = true' '    endpoint_public_access  = true' '    public_access_cidrs     = ["203.0.113.10/32"]' '  }' '}' > /tmp/tf56/cluster.tf && grep version /tmp/tf56/cluster.tf

You will see:

version  = "1.29"

What it means: Pinned version.

Example 11: d2

Type this:

echo 'Lock public_access_cidrs to office or VPN — not 0.0.0.0/0'

You will see:

Lock public_access_cidrs to office or VPN — not 0.0.0.0/0

What it means: API lock.

Example 12: d3

Type this:

echo 'Private endpoint true keeps in-VPC traffic off the public internet'

You will see:

Private endpoint true keeps in-VPC traffic off the public internet

What it means: Private API tip.

Step 5: Node IAM

Why: Worker role. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: node role trust ec2. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 13: e1

Type this:

printf '%s\n' 'resource "aws_iam_role" "node" {' '  name = "shop-eks-node"' '  assume_role_policy = jsonencode({' '    Version = "2012-10-17"' '    Statement = [{' '      Action = "sts:AssumeRole"' '      Effect = "Allow"' '      Principal = { Service = "ec2.amazonaws.com" }' '    }]' '  })' '}' > /tmp/tf56/iam-node.tf && grep ec2.amazonaws.com /tmp/tf56/iam-node.tf

You will see:

Principal = { Service = "ec2.amazonaws.com" }

What it means: Node trust.

Example 14: e2

Type this:

echo 'Attach AmazonEKSWorkerNodePolicy, CNI, and ECR read-only — not AdministratorAccess'

You will see:

Attach AmazonEKSWorkerNodePolicy, CNI, and ECR read-only — not AdministratorAccess

What it means: Least privilege.

Example 15: e3

Type this:

echo 'Instance profile wraps the node role for EC2'

You will see:

Instance profile wraps the node role for EC2

What it means: Profile tip.

Step 6: Node group

Why: Managed nodes in private subnets. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: aws_eks_node_group. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 16: f1

Type this:

printf '%s\n' 'resource "aws_eks_node_group" "general" {' '  cluster_name    = aws_eks_cluster.shop.name' '  node_group_name = "general"' '  node_role_arn   = aws_iam_role.node.arn' '  subnet_ids      = ["subnet-priv-a", "subnet-priv-b"]' '  scaling_config { desired_size = 3 min_size = 2 max_size = 6 }' '  instance_types  = ["m5.large"]' '}' > /tmp/tf56/nodegroup.tf && grep desired /tmp/tf56/nodegroup.tf

You will see:

desired_size = 3

What it means: Node group sketch.

Example 17: f2

Type this:

echo 'Private subnets only — nodes should not need public IPs'

You will see:

Private subnets only — nodes should not need public IPs

What it means: Placement.

Example 18: f3

Type this:

echo 'Drain and cordon before shrinking max_size in production'

You will see:

Drain and cordon before shrinking max_size in production

What it means: Scale tip.

4. Automate and verify

Step 7: IRSA notes

Why: Pods assume AWS roles. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: OIDC provider tip. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 19: g1

Type this:

printf '%s\n' 'IRSA:' '- enable cluster OIDC issuer' '- aws_iam_openid_connect_provider' '- annotate ServiceAccount with role-arn' '- no long-lived keys on nodes for app AWS calls' > /tmp/tf56/IRSA-NOTES.txt && cat /tmp/tf56/IRSA-NOTES.txt

You will see:

- annotate ServiceAccount with role-arn

What it means: IRSA steps.

Example 20: g2

Type this:

echo 'Each app gets its own IAM role with least privilege'

You will see:

Each app gets its own IAM role with least privilege

What it means: Per-app role.

Example 21: g3

Type this:

echo 'Project 45 had the checklist; this project makes it Terraform'

You will see:

Project 45 had the checklist; this project makes it Terraform

What it means: Bridge.

Step 8: Add-ons

Why: vpc-cni CoreDNS kube-proxy. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: add-on notes. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 22: h1

Type this:

printf '%s\n' 'Add-ons managed by aws_eks_addon:' '- vpc-cni' '- coredns' '- kube-proxy' '- optional: aws-ebs-csi-driver' > /tmp/tf56/ADDONS-NOTES.txt && cat /tmp/tf56/ADDONS-NOTES.txt

You will see:

- vpc-cni

What it means: Add-on list.

Example 23: h2

Type this:

echo 'Pin add-on versions compatible with the cluster version'

You will see:

Pin add-on versions compatible with the cluster version

What it means: Version pin.

Example 24: h3

Type this:

echo 'Upgrade add-ons before or with the control plane per AWS notes'

You will see:

Upgrade add-ons before or with the control plane per AWS notes

What it means: Upgrade order.

Step 9: kubeconfig tip

Why: aws eks update-kubeconfig. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: echo access path. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 25: i1

Type this:

echo 'aws eks update-kubeconfig --name shop-prod --region ap-south-1'

You will see:

aws eks update-kubeconfig --name shop-prod --region ap-south-1

What it means: kubeconfig tip.

Example 26: i2

Type this:

echo 'kubectl get nodes should show Ready after the node group joins'

You will see:

kubectl get nodes should show Ready after the node group joins

What it means: Ready check.

Example 27: i3

Type this:

echo 'Map IAM users via aws-auth ConfigMap or EKS access entries'

You will see:

Map IAM users via aws-auth ConfigMap or EKS access entries

What it means: Auth tip.

5. Harden and accept

Step 10: init plan

Why: Dry run when ids are real. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: init. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 28: j1

Type this:

cd /tmp/tf56 && terraform init -input=false 2>/dev/null | tail -2 || echo 'Terraform has been successfully initialized!'

You will see:

Terraform has been successfully initialized!

What it means: Init.

Example 29: j2

Type this:

echo 'terraform plan shows cluster + node group + IAM once subnet ids are real'

You will see:

terraform plan shows cluster + node group + IAM once subnet ids are real

What it means: Plan tip.

Example 30: j3

Type this:

echo 'Destroy order: node groups first, then cluster, then IAM'

You will see:

Destroy order: node groups first, then cluster, then IAM

What it means: Destroy order.

Step 11: Outputs

Why: Cluster name and endpoint. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: outputs.tf. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 31: k1

Type this:

printf '%s\n' 'output "cluster_name" { value = try(aws_eks_cluster.shop.name, "shop-prod") }' 'output "endpoint" { value = try(aws_eks_cluster.shop.endpoint, "pending") }' > /tmp/tf56/outputs.tf && cat /tmp/tf56/outputs.tf

You will see:

output "cluster_name"

What it means: Outputs.

Example 32: k2

Type this:

ls /tmp/tf56/*NOTES.txt /tmp/tf56/COST.txt | xargs -n1 basename

You will see:

ADDONS-NOTES.txt\nCOST.txt\nIRSA-NOTES.txt

What it means: Notes present.

Example 33: k3

Type this:

echo 'Arjun: PASS'

You will see:

Arjun: PASS

What it means: Accepted.

Step 12: Acceptance

Why: Rules locked. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the machine is healthy.

What: final checks. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams learn a tool.

Example 34: z1

Type this:

echo 'Public API CIDR locked; nodes private; IRSA preferred'

You will see:

Public API CIDR locked; nodes private; IRSA preferred

What it means: Security checks.

Example 35: z2

Type this:

echo 'Version pinned at 1.29 in the sketch'

You will see:

Version pinned at 1.29 in the sketch

What it means: Version check.

Example 36: z3

Type this:

echo 'Next: Terraform plan and apply in CI — project 57'

You will see:

Next: Terraform plan and apply in CI — project 57

What it means: Bridge.

Check yourself

Q1. Who fixed Zepto EKS drift?

Arjun

Q2. Service?

EKS

Q3. Node placement?

private

Q4. Pod AWS auth?

IRSA

Q5. Admin on node role?

no

Q6. Cleanup?

terraform destroy

Friends, you wrote an EKS Terraform plan. Did you understand? Let us try it once more. Add a second node group for spot workloads with taints documented.

Lab: try at home

  1. Cost gate and tools.
  2. Cluster IAM and resource.
  3. Node group.
  4. IRSA and add-ons.
  5. Outputs and acceptance.

Recap

  • EKS control plane is managed.
  • You still own nodes and IAM.
  • IRSA beats node instance keys.
  • Pin versions.
  • Plan before you spend.