Skip to main content

Command Palette

Search for a command to run...

Terraform Custom Modules for EKS

Published
3 min read

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

  1. 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.

  2. IAM Module: Handles all identity management. This includes the OIDC integration, which allows Kubernetes pods to assume AWS roles (IRSA).

  3. EKS Module: Deploy the cluster and its worker nodes. It uses Launch Templates for fine-grained node configuration.

  4. 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 module to import the custom modules. Then we link to the main file through the source keyword.

  • azs is availability zones, we take that from the data source and slice it.

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!

More from this blog

Code Companions

32 posts