Create EKS Cluster with VPC using Terraform | Real Time Terraform Modules Implementation
This comprehensive chapter guide details the creation of a production-grade Amazon Elastic Kubernetes Service (EKS) cluster alongside a customized Virtual Private Cloud (VPC), security groups, and auto-scaling worker node groups using modular Terraform configurations.
1. Why Do We Need Modular Infrastructure as Code?
- Manual Overhead Elimination: Provisioning modern cloud architectures—such as an enterprise VPC paired with an EKS cluster and managed auto-scaling node groups—manually through the AWS Management Console is tedious, error-prone, and non-repeatable.
- Enterprise Reproducibility: Organizations require infrastructure defined as code (IaC) to guarantee consistency across development, staging, and production environments.
- Separation of Concerns: Bundling every resource into a single monolithic script creates maintenance nightmares. Breaking down code into modular files (
vpc.tf,eks.tf,security.tf,outputs.tf) ensures developers and DevOps engineers can isolate and troubleshoot network or compute layers independently.
2. Core Mental Model: Terraform to AWS Architecture
The workflow bridges your local environment or build server directly to AWS resources using API credentials managed via the AWS CLI.
3. Step-by-Step Implementation Workflow
To build and manage this infrastructure successfully, follow this sequential execution pipeline:
4. Setting Up Prerequisites: AWS CLI & Terraform
Before writing any Terraform code, your local machine must authenticate with AWS.
Configuring AWS Credentials
Run the configuration command in your terminal:
aws configure
You will be prompted for:
- AWS Access Key ID: Retrieved from the AWS IAM / Root User Security Credentials console.
- AWS Secret Access Key: The corresponding secret string.
- Default region name: e.g.,
us-east-1orus-west-2. - Default output format:
json.
Note: Terraform reads the secure credential files generated by
aws configureunder the hood to authenticate API calls against your AWS account.
Verify installations using:
aws --version
terraform version
5. Structuring the Terraform Project Files
Instead of writing everything in a single main.tf file, partition your project into logical modular files:
6. Implementing the VPC Module (vpc.tf)
Rather than writing raw VPC, subnet, route table, and internet gateway resources from scratch, utilize the official community VPC module from the Terraform Registry.
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.7.0"
name = "prod-vpc"
cidr = var.vpc_cidr
azs = ["us-west-2a", "us-west-2b", "us-west-2c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Environment = "production"
Terraform = "true"
}
}
7. Implementing the EKS Cluster & Auto-Scaling Node Groups (eks.tf)
To ensure unique cluster naming across deployments, integrate a random_string resource coupled with local variables.
resource "random_string" "suffix" {
length = 8
special = false
upper = false
}
locals {
cluster_name = "abi-eks-${random_string.suffix.result}"
}
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 20.0"
cluster_name = local.cluster_name
cluster_version = var.kubernetes_version
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
cluster_endpoint_public_access = true
eks_managed_node_groups = {
worker_nodes = {
min_size = 2
max_size = 6
desired_size = 2
instance_types = ["t3.medium"]
ami_type = "AL2_x86_64"
vpc_security_group_ids = [aws_security_group.worker_group_mgmt.id]
}
}
}
8. Defining Outputs (outputs.tf)
To retrieve essential cluster metadata immediately after execution without logging into the AWS Console, define output blocks:
output "cluster_id" {
description = "The Amazon Resource Name (ARN) of the EKS cluster"
value = module.eks.cluster_id
}
output "cluster_endpoint" {
description = "Endpoint for EKS control plane"
value = module.eks.cluster_endpoint
}
output "cluster_name" {
description = "Generated EKS Cluster Name"
value = local.cluster_name
}
9. Executing the Infrastructure Pipeline
Open your terminal inside the project directory and execute the initialization and deployment commands:
1. Initialize Terraform
terraform init
- What happens here: Terraform reads
versions.tf, downloads the specified provider plugins (registry.terraform.io/hashicorp/aws), and pulls down community modules (vpcandeks) into the hidden.terraform/directory.
2. Review the Execution Plan
terraform plan
- What happens here: Terraform evaluates your current state against desired configuration files and outputs a detailed ledger showing that 55 resources will be added, 0 changed, and 0 destroyed.
3. Apply the Configuration
terraform apply --auto-approve
- What happens here: Terraform provisions resources in dependency order (VPC and Internet Gateways first, followed by subnets, route tables, security groups, the EKS control plane, and finally the auto-scaling managed node groups). This process typically takes 10 to 13 minutes.
10. Granting Cluster Access & Configuring kubectl
By default, even the AWS root user or IAM administrator who created the EKS cluster lacks direct Kubernetes object visibility until explicit access entries are configured.
Fixing "No Resources Found" / Access Denied Errors
- Navigate to the Amazon EKS Console -> Select your cluster (
abi-eks-xxxxxxxx). - Go to the Access tab -> Click Create access entry.
- Select your IAM Principal ARN (e.g., your root or admin IAM role).
- Click Next -> Assign the policy
AmazonEKSClusterAdminPolicy. - Click Create.
Configuring Local kubectl Access
Run the following AWS CLI command generated by your cluster region and name to update your local kubeconfig file:
aws eks update-kubeconfig --region us-west-2 --name abi-eks-xxxxxxxx
Verify your worker nodes are successfully registered and running:
kubectl get nodes
Expected Output: Two active t3.medium worker nodes in Ready state managed by the auto-scaling group (scaling up to 6 nodes under heavy workloads).
Summary and Key Takeaways
- Infrastructure as Code (IaC): Terraform automates complex multi-tier cloud deployments reliably and consistently across environments.
- Modular Design Pattern: Breaking code into dedicated files (
vpc.tf,eks.tf) and leveraging official Terraform Registry modules (terraform-aws-modules) drastically reduces boilerplate code and maintenance overhead. - Auto-Scaling Node Groups: EKS managed node groups provide dynamic scaling capabilities (
min_size = 2,max_size = 6) to handle varying traffic loads seamlessly. - Randomized Naming: Using
random_stringprevents resource naming collisions when provisioning globally unique cloud resources like EKS clusters. - Explicit EKS Access Entries: Creating an EKS cluster does not automatically grant Kubernetes API object access to the creator; explicit IAM access entries and policies must be provisioned.
- Cost Management: Always execute
terraform destroyafter completing labs or testing environments to terminate expensive resources (like EC2 instances and NAT Gateways) and avoid unexpected billing charges.