The Problem
Many Terraform projects start well but quickly become unmanageable: a single monolithic state, copy-paste between environments, plans that take 10 minutes.
Recommended Module Architecture
infra/
├── modules/
│ ├── api-gateway/ # API Gateway module
│ ├── lambda/ # Generic Lambda module
│ ├── dynamodb/ # DynamoDB module
│ ├── monitoring/ # CloudWatch + alerts module
│ └── networking/ # VPC / Security Groups module
├── environments/
│ ├── dev/
│ ├── staging/
│ └── prod/
└── terragrunt.hcl # Root Terragrunt configKey Principles
- One module = one responsibility: separate API Gateway, Lambda, DynamoDB
- Typed variables: use Terraform's complex types
- Explicit outputs: each module exposes what others need
- Terragrunt for DRY: avoid duplication between environments
Reusable Lambda Module
A good Lambda module should accept:
- Source code (S3 or local)
- Memory/timeout configuration
- Environment variables
- Additional IAM policies
- Monitoring configuration
Terragrunt: The Game Changer
Terragrunt eliminates duplication between environments. A single terragrunt.hcl per environment referencing modules with specific variables.
Observed Results
- Terraform plans from 10min to 30s
- New dev onboarding: 1 day instead of 1 week
- Deployments reproducible and auditable
- Automated drift detection
Need to structure your IaC? Contact me.