-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Production-grade reusable Terraform modules for AWS infrastructure Built at AU Technology Consulting | Used across 15+ enterprise services
| Page | Description |
|---|---|
| Home | Library overview, all modules, design principles |
| Getting Started | Prerequisites, installation, first deployment |
| Module: VPC | Networking — VPC, subnets, NAT, flow logs |
| Module: EKS Cluster | Kubernetes cluster with IRSA and encryption |
| Module: RDS Multi-AZ | MySQL HA with 99.99% SLA design |
| Module: ALB | Application Load Balancer with WAF |
| Module: S3 Secure | Encrypted, private S3 with lifecycle |
| Module: IRSA | IAM Roles for Service Accounts |
| Module: Karpenter | EKS autoscaler with Spot adoption |
| Module: ASG | Auto Scaling Group with mixed instances |
| Module: EFS | Encrypted shared file storage |
| Module: Security Group | Reusable least-privilege SGs |
| Module: NAT Gateway | HA outbound internet |
| Module: VPC Endpoints | Private AWS service access |
| Complete Example | All modules working together |
| Design Principles | Standards, conventions, security |
| Contributing | How to add or improve modules |
Every module in this library follows these non-negotiable standards:
No module creates an insecure resource by default. Examples:
- S3 buckets: public access blocked, encryption enabled, TLS-only policy
- RDS: Multi-AZ enabled, encryption enabled, no public access
- Security groups: no
0.0.0.0/0ingress rules without explicit flag - IAM policies: no wildcard actions without explicit justification
Every variable has a description. No variable is undocumented.
Sensitive variables are marked sensitive = true.
variable "db_password" {
description = "Master database password. Retrieve from Vault or Secrets Manager."
type = string
sensitive = true # Redacted from plan/apply output
}
All resources created by modules accept a tags variable and apply it
to every resource. This enables accurate cost allocation.
variable "tags" {
description = "Tags applied to all resources for cost allocation and inventory"
type = map(string)
default = {}
}
Critical inputs are validated using Terraform validation blocks:
variable "cidr" {
validation {
condition = can(cidrhost(var.cidr, 0))
error_message = "Must be a valid IPv4 CIDR block."
}
}
All modules are safe to run multiple times. Running terraform apply
twice on unchanged configuration produces no changes.
Every module outputs the IDs, ARNs, and names of the resources it creates, enabling other modules to depend on it:
# VPC outputs used by EKS module
module "vpc" { ... }
module "eks" {
vpc_id = module.vpc.vpc_id
private_subnet_ids = module.vpc.private_subnet_ids
}
Infrastructure has natural dependencies. Deploy in this order:
Step 1: Networking (no dependencies)
module.vpc → module.nat_gateway → module.vpc_endpoints
Step 2: Security foundation
module.irsa_roles (depends on: EKS OIDC provider)
Step 3: Compute
module.eks_cluster (depends on: VPC)
module.karpenter (depends on: EKS cluster)
Step 4: Data layer
module.rds (depends on: VPC)
module.efs (depends on: VPC)
module.s3 (no VPC dependency)
Step 5: Traffic management
module.alb (depends on: VPC)
# provider.tf
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
}
provider "aws" {
region = "ap-south-1"
}
main.tf
module "vpc" {
source = "github.com/kiransurya-devops/aws-terraform-modules//modules/vpc"
name = "my-env"
cidr = "10.0.0.0/16"
availability_zones = ["ap-south-1a", "ap-south-1b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
enable_flow_logs = true
tags = { Environment = "dev", ManagedBy = "terraform" }
}
module "s3_state" {
source = "github.com/kiransurya-devops/aws-terraform-modules//modules/s3-secure"
bucket_name = "my-terraform-state"
enable_versioning = true
tags = { Environment = "dev" }
}
aws-terraform-modules/
├── README.md # Entry point, all modules listed
├── modules/
│ ├── vpc/
│ │ ├── main.tf # Resources
│ │ ├── variables.tf # All inputs documented
│ │ ├── outputs.tf # All outputs documented
│ │ └── README.md # Usage, inputs table, outputs table
│ ├── eks-cluster/ # Same structure
│ ├── rds-multi-az/
│ ├── alb/
│ ├── asg/
│ ├── s3-secure/
│ ├── efs/
│ ├── karpenter/
│ ├── irsa/
│ ├── security-group/
│ ├── nat-gateway/
│ └── vpc-endpoints/
├── examples/
│ ├── complete-eks-platform/ # Full production example
│ │ ├── main.tf # Uses all relevant modules
│ │ ├── variables.tf
│ │ └── terraform.tfvars.example
│ └── complete-networking/ # Networking-only example
└── .github/
└── workflows/
└── ci.yml # Validate all modules on every PR
Every pull request automatically runs:
Job 1: Format check
terraform fmt -check -recursive
(fails if any file needs formatting)
Job 2: Validate (parallel, one per module)
terraform init -backend=false
terraform validate
(runs for all 12 modules simultaneously)
Job 3: Security scan
Checkov — CIS AWS benchmark checks
Results uploaded to GitHub Security tab
Job 4: Secret scan
Gitleaks — no credentials in module code
Job 5: Documentation check
Verify every module has a README.md
No PR is merged unless all jobs pass.
Kiran S — Senior DevOps & Platform Engineer
- LinkedIn: linkedin.com/in/kiransurya-devops
- GitHub: github.com/kiransurya-devops
# AWS Terraform Modules Library — Project WikiThese modules are extracted from real enterprise production deployments. Every module has been used in systems maintaining 99.99% availability SLA.
Production-grade reusable Terraform modules for AWS infrastructure Built at AU Technology Consulting | Used across 15+ enterprise services
| Page | Description |
|---|---|
| [Home](Home) | Library overview, all modules, design principles |
| [Getting Started](Getting-Started) | Prerequisites, installation, first deployment |
| [Module: VPC](Module-VPC) | Networking — VPC, subnets, NAT, flow logs |
| [Module: EKS Cluster](Module-EKS-Cluster) | Kubernetes cluster with IRSA and encryption |
| [Module: RDS Multi-AZ](Module-RDS-Multi-AZ) | MySQL HA with 99.99% SLA design |
| [Module: ALB](Module-ALB) | Application Load Balancer with WAF |
| [Module: S3 Secure](Module-S3-Secure) | Encrypted, private S3 with lifecycle |
| [Module: IRSA](Module-IRSA) | IAM Roles for Service Accounts |
| [Module: Karpenter](Module-Karpenter) | EKS autoscaler with Spot adoption |
| [Module: ASG](Module-ASG) | Auto Scaling Group with mixed instances |
| [Module: EFS](Module-EFS) | Encrypted shared file storage |
| [Module: Security Group](Module-Security-Group) | Reusable least-privilege SGs |
| [Module: NAT Gateway](Module-NAT-Gateway) | HA outbound internet |
| [Module: VPC Endpoints](Module-VPC-Endpoints) | Private AWS service access |
| [Complete Example](Complete-EKS-Platform-Example) | All modules working together |
| [Design Principles](Design-Principles) | Standards, conventions, security |
| [Contributing](Contributing) | How to add or improve modules |
This module library was built to solve a real problem: engineers across multiple teams were writing similar Terraform code independently, with different approaches to security, naming, and tagging. Each inconsistency became a potential misconfiguration.
The module library standardises all AWS infrastructure patterns. Any team
needs to write: module "vpc" { source = "./modules/vpc" ... } and they
get a production-ready, security-hardened, correctly-tagged VPC.
| Metric | Result |
|---|---|
| Provisioning errors | ↓ 70% across all teams |
| Time per environment cycle | 8 hours saved per cycle |
| Modules in library | 12 production-tested modules |
| Services using these modules | 15+ microservices |
| Security standard | CIS AWS Benchmark aligned |
| Compliance | PCI-DSS configuration |
| Module | Version | Description |
|---|---|---|
| [vpc](Module-VPC) | 1.2.0 | Multi-AZ VPC with public/private/database tiers, NAT Gateway HA, VPC Flow Logs |
| [nat-gateway](Module-NAT-Gateway) | 1.0.0 | NAT Gateway with EIP management and route tables |
| [vpc-endpoints](Module-VPC-Endpoints) | 1.1.0 | Interface and gateway endpoints for S3, ECR, Secrets Manager |
| [security-group](Module-Security-Group) | 1.0.0 | Reusable SG patterns with documented rules |
| Module | Version | Description |
|---|---|---|
| [eks-cluster](Module-EKS-Cluster) | 2.1.0 | EKS cluster with OIDC/IRSA, KMS encryption, audit logging |
| [asg](Module-ASG) | 1.3.0 | Auto Scaling Group with launch templates and mixed instances |
| [karpenter](Module-Karpenter) | 1.0.0 | Karpenter autoscaler with Spot preferences and NodePools |
| Module | Version | Description |
|---|---|---|
| [irsa](Module-IRSA) | 1.1.0 | IAM Roles for Service Accounts — resolved critical audit finding |
| Module | Version | Description |
|---|---|---|
| [rds-multi-az](Module-RDS-Multi-AZ) | 1.4.0 | MySQL Multi-AZ with PITR, 99.99% SLA, automated monitoring |
| [s3-secure](Module-S3-Secure) | 1.2.0 | S3 with encryption, versioning, TLS-only policy, lifecycle |
| [efs](Module-EFS) | 1.0.0 | Encrypted EFS with mount targets and access points |
| Module | Version | Description |
|---|---|---|
| [alb](Module-ALB) | 1.3.0 | ALB with HTTPS, WAF integration, access logs, health checks |
Every module in this library follows these non-negotiable standards:
No module creates an insecure resource by default. Examples:
- S3 buckets: public access blocked, encryption enabled, TLS-only policy
- RDS: Multi-AZ enabled, encryption enabled, no public access
- Security groups: no
0.0.0.0/0ingress rules without explicit flag - IAM policies: no wildcard actions without explicit justification
Every variable has a description. No variable is undocumented.
Sensitive variables are marked sensitive = true.
variable "db_password" {
description = "Master database password. Retrieve from Vault or Secrets Manager."
type = string
sensitive = true # Redacted from plan/apply output
}All resources created by modules accept a tags variable and apply it
to every resource. This enables accurate cost allocation.
variable "tags" {
description = "Tags applied to all resources for cost allocation and inventory"
type = map(string)
default = {}
}Critical inputs are validated using Terraform validation blocks:
variable "cidr" {
validation {
condition = can(cidrhost(var.cidr, 0))
error_message = "Must be a valid IPv4 CIDR block."
}
}All modules are safe to run multiple times. Running terraform apply
twice on unchanged configuration produces no changes.
Every module outputs the IDs, ARNs, and names of the resources it creates, enabling other modules to depend on it:
# VPC outputs used by EKS module
module "vpc" { ... }
module "eks" {
vpc_id = module.vpc.vpc_id
private_subnet_ids = module.vpc.private_subnet_ids
}Infrastructure has natural dependencies. Deploy in this order:
Step 1: Networking (no dependencies)
module.vpc → module.nat_gateway → module.vpc_endpoints
Step 2: Security foundation
module.irsa_roles (depends on: EKS OIDC provider)
Step 3: Compute
module.eks_cluster (depends on: VPC)
module.karpenter (depends on: EKS cluster)
Step 4: Data layer
module.rds (depends on: VPC)
module.efs (depends on: VPC)
module.s3 (no VPC dependency)
Step 5: Traffic management
module.alb (depends on: VPC)
# provider.tf
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
}
provider "aws" {
region = "ap-south-1"
}
# main.tf
module "vpc" {
source = "github.com/kiransurya-devops/aws-terraform-modules//modules/vpc"
name = "my-env"
cidr = "10.0.0.0/16"
availability_zones = ["ap-south-1a", "ap-south-1b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
enable_flow_logs = true
tags = { Environment = "dev", ManagedBy = "terraform" }
}
module "s3_state" {
source = "github.com/kiransurya-devops/aws-terraform-modules//modules/s3-secure"
bucket_name = "my-terraform-state"
enable_versioning = true
tags = { Environment = "dev" }
}aws-terraform-modules/
├── README.md # Entry point, all modules listed
├── modules/
│ ├── vpc/
│ │ ├── main.tf # Resources
│ │ ├── variables.tf # All inputs documented
│ │ ├── outputs.tf # All outputs documented
│ │ └── README.md # Usage, inputs table, outputs table
│ ├── eks-cluster/ # Same structure
│ ├── rds-multi-az/
│ ├── alb/
│ ├── asg/
│ ├── s3-secure/
│ ├── efs/
│ ├── karpenter/
│ ├── irsa/
│ ├── security-group/
│ ├── nat-gateway/
│ └── vpc-endpoints/
├── examples/
│ ├── complete-eks-platform/ # Full production example
│ │ ├── main.tf # Uses all relevant modules
│ │ ├── variables.tf
│ │ └── terraform.tfvars.example
│ └── complete-networking/ # Networking-only example
└── .github/
└── workflows/
└── ci.yml # Validate all modules on every PR
Every pull request automatically runs:
Job 1: Format check
terraform fmt -check -recursive
(fails if any file needs formatting)
Job 2: Validate (parallel, one per module)
terraform init -backend=false
terraform validate
(runs for all 12 modules simultaneously)
Job 3: Security scan
Checkov — CIS AWS benchmark checks
Results uploaded to GitHub Security tab
Job 4: Secret scan
Gitleaks — no credentials in module code
Job 5: Documentation check
Verify every module has a README.md
No PR is merged unless all jobs pass.
Kiran S — DevOps & Platform Engineer
- LinkedIn: [linkedin.com/in/kiransurya-devops](https://linkedin.com/in/kiransurya-devops)
- GitHub: [github.com/kiransurya-devops](https://github.com/kiransurya-devops)
These modules are extracted from real enterprise production deployments. Every module has been used in systems maintaining 99.99% availability SLA.