EKS Auto Mode with Terraform

Amazon EKS Auto Mode represents a major evolution in managed Kubernetes on AWS. It delivers an opinionated, fully automated infrastructure experience by managing compute (Karpenter), networking (VPC CNI & ELB Controller), storage (EBS CSI), and security directly as part of the EKS control plane lifecycle.
📁 Source Code: aws-eks-terraform / EKS-Cluster-auto-mode
📺 Video Walkthrough
Why Choose EKS Auto Mode?
In standard EKS, platform teams are responsible for managing, upgrading, and reconciling multiple add-ons (VPC-CNI, CoreDNS, Kube-Proxy, Karpenter, AWS Load Balancer Controller, and EBS CSI Driver). EKS Auto Mode offloads this maintenance to AWS.
| Capability | Standard EKS | EKS Auto Mode |
|---|---|---|
| Node Provisioning | Manual Managed NodeGroups / Karpenter setup | Built-in Karpenter with default NodePool |
| Storage Driver | Self-managed EBS CSI Driver Add-on | Automated storage_config block storage |
| Ingress & Load Balancing | Self-managed AWS Load Balancer Controller | Automated elastic_load_balancing network config |
| Pod Networking | Self-managed VPC CNI DaemonSet | Automated AWS-managed VPC CNI |
| Cluster Authentication | Legacy ConfigMap or Access Entries | Enforced EKS Access Entries (API mode) |
Terraform Implementation
Step 1. Configure Subnet Tags for Load Balancer Discovery
Ensure subnets have appropriate discovery tags:
vpc.tf
public_subnet_tags = {
"kubernetes.io/role/elb" = "1" # Tag for external Application / Network Load Balancers
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = "1" # Tag for internal Load Balancers
}
Step 2. Create IAM Roles for Cluster and Nodes
EKS Auto Mode requires specific IAM policies for both the cluster control plane and the auto-provisioned worker nodes.
iam.tf
# 1. Node Role
resource "aws_iam_role" "node" {
name = "eks-auto-node-${var.cluster_name}"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = ["sts:AssumeRole"]
Effect = "Allow"
Principal = { Service = "ec2.amazonaws.com" }
}
]
})
}
resource "aws_iam_role_policy_attachment" "node_minimal" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodeMinimalPolicy"
role = aws_iam_role.node.name
}
resource "aws_iam_role_policy_attachment" "node_ecr" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPullOnly"
role = aws_iam_role.node.name
}
# 2. Cluster Role
resource "aws_iam_role" "cluster" {
name = "eks-cluster-${var.cluster_name}"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = ["sts:AssumeRole", "sts:TagSession"]
Effect = "Allow"
Principal = { Service = "eks.amazonaws.com" }
}
]
})
}
resource "aws_iam_role_policy_attachment" "cluster_policies" {
for_each = toset([
"arn:aws:iam::aws:policy/AmazonEKSClusterPolicy",
"arn:aws:iam::aws:policy/AmazonEKSComputePolicy",
"arn:aws:iam::aws:policy/AmazonEKSBlockStoragePolicy",
"arn:aws:iam::aws:policy/AmazonEKSLoadBalancingPolicy",
"arn:aws:iam::aws:policy/AmazonEKSNetworkingPolicy"
])
policy_arn = each.value
role = aws_iam_role.cluster.name
}
Step 3. Provision the EKS Auto Cluster
eks-auto.tf
resource "aws_eks_cluster" "eks_auto" {
name = "eks-auto-demo"
version = "1.31"
role_arn = aws_iam_role.cluster.arn
access_config {
authentication_mode = "API"
}
bootstrap_self_managed_addons = false
compute_config {
enabled = true
node_pools = ["general-purpose"]
node_role_arn = aws_iam_role.node.arn
}
kubernetes_network_config {
elastic_load_balancing {
enabled = true
}
}
storage_config {
block_storage {
enabled = true
}
}
vpc_config {
endpoint_private_access = true
endpoint_public_access = true
subnet_ids = module.vpc.private_subnets
}
depends_on = [aws_iam_role_policy_attachment.cluster_policies]
}
Step 4. EKS Access Entry (Cluster Admin)
Grant cluster administrator permissions to the identity applying Terraform:
access-entries.tf
data "aws_caller_identity" "current" {}
resource "aws_eks_access_entry" "admin" {
cluster_name = aws_eks_cluster.eks_auto.name
principal_arn = data.aws_caller_identity.current.arn
type = "STANDARD"
}
resource "aws_eks_access_policy_association" "admin" {
cluster_name = aws_eks_cluster.eks_auto.name
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
principal_arn = data.aws_caller_identity.current.arn
access_scope {
type = "cluster"
}
}
Connect and Validate
# 1. Update kubeconfig
aws eks --region eu-west-1 update-kubeconfig --name eks-auto-demo
# 2. Verify cluster status
kubectl cluster-info
# 3. Check registered NodePools and IngressClasses
kubectl get nodepool,ingressclass,nodes
Ingress Architecture Recommendation
While EKS Auto Mode includes a built-in Ingress controller, adopting the Kubernetes Gateway API (e.g. Envoy Gateway) is recommended for production environments. Gateway API provides faster health checking, seamless traffic shifting, and avoids traditional ALB target group registration delays.