Yogita Sharma

Yogita Sharma

Platform Engineer

AWS | Kubernetes | Terraform | CI/CD

Gurugram, India

Back to Blog

Designing Reusable Terraform Modules for AWS at Scale

· 7 min read
Terraform AWS IaC EKS

The Problem with Copy-Paste Infrastructure

When I joined Skillmine Technologies, each project team was maintaining their own Terraform configurations. The result was predictable:

  • Inconsistent security configurations across projects
  • Duplicated effort when AWS released new features or best practices changed
  • Drift between environments because staging and production were configured differently

I set out to build a library of reusable Terraform modules that would standardize our AWS infrastructure.

Module Design Principles

1. Opinionated Defaults, Flexible Overrides

Every module ships with secure, production-ready defaults. Teams can override specific values, but the baseline is always secure:

module "vpc" {
  source = "git::https://gitlab.internal/infra/terraform-modules.git//vpc"

  name               = "app-vpc"
  cidr_block         = "10.0.0.0/16"
  availability_zones = ["ap-south-1a", "ap-south-1b", "ap-south-1c"]

  # Defaults: private subnets, NAT gateway, flow logs enabled
  # Override only what's different
  enable_vpn_gateway = true
}

2. Composable, Not Monolithic

Instead of one massive module that creates everything, I built small, focused modules that compose together:

  • vpc — VPC, subnets, route tables, NAT gateways
  • eks — EKS cluster, node groups, IRSA roles
  • rds — RDS instances with multi-AZ, automated backups
  • iam — IAM roles and policies following least-privilege

3. Built-in Compliance

Security scanning is embedded in the module CI pipeline using tfsec and checkov. Every merge request is automatically scanned, and modules can’t be published with critical findings.

High Availability Pattern

One module I’m particularly proud of is the HA application deployment pattern:

module "ha_app" {
  source = "git::https://gitlab.internal/infra/terraform-modules.git//ha-app"

  app_name    = "payment-service"
  environment = "production"

  # Multi-AZ deployment
  vpc_id             = module.vpc.vpc_id
  private_subnet_ids = module.vpc.private_subnet_ids

  # Auto Scaling
  min_size     = 2
  max_size     = 10
  desired_size = 3

  # ALB
  health_check_path = "/health"
  certificate_arn   = data.aws_acm_certificate.main.arn
}

This single module call provisions:

  • Application Load Balancer with HTTPS
  • Auto Scaling Group spread across AZs
  • Launch template with hardened AMI
  • CloudWatch alarms for scaling triggers
  • Security groups with least-privilege rules

Results

  • Provisioning time reduced from days to hours for new projects
  • Zero critical security findings in infrastructure audits
  • Consistent environments — staging mirrors production exactly
  • Self-service — dev teams can provision infrastructure without platform team involvement

The key insight is that good Terraform modules aren’t just about DRY code — they’re about encoding organizational knowledge and security requirements into reusable building blocks.