Terraform Custom Modules for EKS
Project Architecture

Modules in Terraform
Reusable piece of code. Categorized into Public Module (AWS, Azure, GCP, Oracle, etc.), Partnet Module (Managed by Hashicorp + Partner), then Custom Module (Users modules for their use case)
Creating the Structure
All the custom modules will be placed in the root folder sub-folder structure. Therefore, the reference for the custom modules will be present under the custom modules.
Here, the variable.tf In the VPC subfolder, we will only have the name, and the values will be given from the root folder, given the already described that we take control of the code.
variable "vpc_cidr" {
description = "CIDR block for VPC" # no values only initialization
type = string
}
variable.tf In the root folder have the values.
variable "vpc_cidr" {
description = "CIDR block for VPC"
type = string
default = "10.0.0.0/16" # values passed from the root module
}
EKS Modular Code Structure
This project follows a highly modular Terraform structure for deploying a production-ready EKS cluster. It separates concerns across networking, security, and orchestration.
Directory Structure
code/
├── main.tf # Root configuration (calls modules)
├── variables.tf # Global input variables
├── outputs.tf # Global outputs (Cluster endpoint, etc.)
├── provider.tf # AWS & Kubernetes providers
└── modules/ # Custom reusable modules
├── vpc/ # Networking (VPC, Subnets, NAT Gateway)
├── iam/ # Security (Roles, OIDC Provider, IRSA)
├── eks/ # Orchestration (Control Plane, Node Groups)
└── secrets-manager/# Configuration (KMS, Secrets storage)
How it works
VPC Module: Sets up the network core. EKS nodes live in private subnets, while the NAT Gateway provides internet access for updates and API calls.
IAM Module: Handles all identity management. This includes the OIDC integration, which allows Kubernetes pods to assume AWS roles (IRSA).
EKS Module: Deploy the cluster and its worker nodes. It uses Launch Templates for fine-grained node configuration.
Secrets Manager: Provides a secure way to store and inject sensitive data into your Kubernetes workloads via KMS encryption.
Important Keywords
# Data sources
data "aws_availability_zones" "available" {
state = "available"
}
# Custom VPC Module
module "vpc" {
source = "./modules/vpc"
name_prefix = var.cluster_name
vpc_cidr = var.vpc_cidr
azs = slice(data.aws_availability_zones.available.names, 0, 3)
private_subnets = var.private_subnets
public_subnets = var.public_subnets
enable_nat_gateway = true
single_nat_gateway = true
# Required tags for EKS
public_subnet_tags = {
"kubernetes.io/role/elb" = "1"
"kubernetes.io/cluster/${var.cluster_name}" = "shared"
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = "1"
"kubernetes.io/cluster/${var.cluster_name}" = "shared"
}
tags = {
Environment = var.environment
Terraform = "true"
Project = "EKS-Day20"
}
}
We use
moduleto import the custom modules. Then we link to the main file through thesourcekeyword.azsis availability zones, we take that from the data source andsliceit.
The main idea here is that we could interlink the files, from the custom module to the root module. No custom module can talk to another module directly, but can take the values from the root module’s output file to interlink the communication.
Checkout the repo: here
Video reference:
Arigato!