AWS with Terraform (Day 20)

Terraform Custom Modules for EKS: From Zero to Production

As Terraform projects grow, a single flat configuration quickly becomes hard to manage, review, and scale. This becomes especially clear when provisioning complex platforms like Amazon EKS, where networking, IAM, cluster configuration, and secrets management are tightly coupled but conceptually separate concerns.

On Day 20 of my AWS with Terraform journey, I focused on designing and using custom Terraform modules to build a production-ready EKS architecture. This day was less about writing individual resources and more about learning how to structure infrastructure like real engineering systems.


Why Terraform Modules Matter in Production

Terraform modules allow you to package infrastructure logic into reusable, versioned units. Instead of duplicating the same VPC, IAM, or EKS code across environments and repositories, modules let you encapsulate complexity behind well-defined inputs and outputs.

In production environments, this provides several advantages:

  • Consistent infrastructure patterns across teams and environments

  • Reduced blast radius by controlling what consumers can configure

  • Safer upgrades through versioned module releases

  • Cleaner root configurations focused on orchestration, not implementation

Modules are not just a convenience feature. They are foundational to scalable Infrastructure as Code.


Root Module vs Custom Modules

Terraform always starts execution from the root module, which is simply the directory where you run terraform init and terraform apply. Any subdirectory referenced using a module block becomes a child module.

Key principle:
Modules never talk to each other directly.

All communication flows through the root module using inputs and outputs:

  • Root passes values into a module using variables

  • Module exposes results using outputs

  • Root reads outputs and passes them to other modules

This design enforces loose coupling and makes infrastructure behavior explicit.


Production-Style EKS Module Architecture

For a clean and maintainable EKS setup, I followed a modular architecture that separates responsibilities clearly.

Typical module boundaries:

VPC Module

  • VPC creation

  • Public and private subnets

  • Internet gateway and NAT gateway

  • Route tables and associations

  • Subnet tagging for Kubernetes

IAM Module

  • EKS cluster role

  • Node group roles

  • Policy attachments

  • Instance profiles

EKS Module

  • EKS cluster

  • Managed node groups

  • OIDC provider for IRSA

  • Kubernetes versioning

Secrets Module

  • Secrets Manager or Parameter Store

  • Centralized handling of sensitive values

  • Outputs only expose ARNs or names, never secrets

This structure mirrors how production teams design infrastructure ownership and boundaries.


How Data and Values Flow Between Modules

A common real-world pattern used in this setup:

  1. Root module uses data sources to fetch availability zones

  2. Root passes AZs into the VPC module

  3. VPC module creates subnets and outputs subnet IDs

  4. Root reads subnet IDs and passes them into the EKS module

  5. EKS module uses those subnets to create the cluster and node groups

This keeps modules reusable and region-agnostic while allowing the root module to control environment-specific logic.


Key Terraform Patterns Used

Several important Terraform patterns become critical when working with modules:

  • Typed variables such as list(string), map(string), and bool

  • Merging standard tags with module-specific tags using merge()

  • Keeping data sources in the root module where possible

  • Exposing only necessary outputs to reduce coupling

  • Pinning module versions using Git tags for stability

These patterns significantly reduce surprises during upgrades and reviews.


Best Practices Learned

  • Start with small modules and expand incrementally

  • Do not over-expose variables; lock down what should not change

  • Version modules and always reference them using tags

  • Document module inputs and outputs clearly

  • Treat modules like internal libraries, not copy-paste folders

The moment you think of Terraform modules the same way you think of application packages, infrastructure design becomes much clearer.


Diagram




Final Thoughts

Custom Terraform modules transform infrastructure from scripts into systems. For EKS in particular, modular design is the difference between a demo cluster and a production-grade platform.

By separating VPC, IAM, EKS, and secrets into well-defined modules and letting the root module orchestrate them, infrastructure becomes reusable, testable, and safe to evolve.

Day 20 reinforced an important lesson:
Good infrastructure is not just about what you provision, but how you structure and control it.

Here is the session link : 


 

Comments

Popular posts from this blog

AWS with Terraform (Day 01)

AWS with Terraform (Day 27)

AWS with Terraform (Day 02)