Collection of 13 Terraform modules published on the Terraform Registry for deploying serverless architectures on AWS, with 12 examples covering basic ECS to full-stack CRUD with DynamoDB and AgentCore with MCP.
A collection of 13 reusable Terraform modules for deploying serverless architectures on AWS. Published on the Terraform Registry and available as open source on GitHub.
The project includes 12 complete examples — each with its own deploy.sh, architecture documentation, and ready-to-run Terraform code. Modules follow AWS Well-Architected Framework best practices: security, reliability, operational excellence, performance, and cost optimization.
The 13 modules cover the infrastructure needed for serverless and container-based applications:
| Module | Description | Key features |
|---|---|---|
| vpc | Multi-AZ VPC | NAT gateways, VPC endpoints, flow logs |
| ecr | Container registry | Encryption, lifecycle policies, image scanning |
| ecs | Fargate service | Auto-scaling, Container Insights, Spot |
| lambda | Lambda functions | Container images, DLQ, retry policies, alarms |
| alb | Application Load Balancer | Access logs, HTTPS, health checks |
| sqs | SQS message queues | FIFO, DLQ, encryption, long polling |
| sns | SNS pub/sub | Email, SQS, Lambda subscriptions, filtering |
| dynamodb | DynamoDB NoSQL | Encryption, PITR, auto-scaling |
| api-gateway | HTTP API (v2) | Throttling, logging, X-Ray |
| api-gateway-v1 | REST API (v1) | OpenAPI/Swagger, VPC Link |
| cloudfront-s3 | CDN + static hosting | SPA routing, OAC, custom domains |
| waf | Web Application Firewall | Rate limiting, IP filtering, managed rules |
| cloudwatch-alarms | Monitoring | CPU, memory, response time, error rates |
The 12 examples are organized as a progressive learning path:
| Example | Pattern | Components | Link |
|---|---|---|---|
| ecs-app | ALB → ECS | VPC, ALB, ECS, ECR | code |
| lambda-function | Lambda Function URL | Lambda, ECR, CloudWatch, SNS, SQS | code |
| Example | Pattern | Components | Link |
|---|---|---|---|
| rest-api-service | REST API + VPC Link | API Gateway v1, NLB, ALB, ECS | code |
| openapi-rest-api | REST API + Swagger | API Gateway v1, OpenAPI 3.0 → Swagger 2.0, ECS | code |
| openapi-http-api | HTTP API + OpenAPI | API Gateway v2, OpenAPI 3.0, ECS | code |
| Example | Pattern | Components | Link |
|---|---|---|---|
| crud-api-rest | REST API + DynamoDB + React | API Gateway v1, ECS, DynamoDB, CloudFront, WAF | code |
| crud-api-http | HTTP API + DynamoDB + React | API Gateway v2, ECS, DynamoDB, CloudFront | code |
| Example | Pattern | Components | Link |
|---|---|---|---|
| sqs-queue | Lambda + SQS + DLQ | SQS FIFO, Dead Letter Queue, Lambda | code |
| sns-fanout | SNS → multiple SQS | SNS Topic, attribute filtering, multiple queues | code |
| Example | Pattern | Components | Link |
|---|---|---|---|
| api-gateway-multi-service | Multi-service | API Gateway, VPC Link, FastAPI + Node MCP | code |
| mcp-agent-runtime | MCP Server + AgentCore | ECS, ALB, Bedrock AgentCore Gateway | code |
| agentcore-full | Full AgentCore | ECS, Lambda, SQS, SNS, OpenSearch, Bedrock Agent | code |
The most basic example — a FastAPI application behind an ALB on ECS Fargate:
module "vpc" {
source = "jonmatum/serverless-modules/aws//modules/vpc"
name = "my-app-vpc"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-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
single_nat_gateway = true
}
module "alb" {
source = "jonmatum/serverless-modules/aws//modules/alb"
name = "my-app-alb"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.public_subnet_ids
target_port = 8000
health_check_path = "/health"
}
module "ecr" {
source = "jonmatum/serverless-modules/aws//modules/ecr"
repository_name = "my-app"
scan_on_push = true
}
module "ecs" {
source = "jonmatum/serverless-modules/aws//modules/ecs"
cluster_name = "my-app-cluster"
service_name = "my-app-service"
container_name = "my-app"
container_image = "${module.ecr.repository_url}:latest"
container_port = 8000
subnet_ids = module.vpc.private_subnet_ids
target_group_arn = module.alb.target_group_arn
enable_autoscaling = true
enable_container_insights = true
}Full-stack application with React, FastAPI, DynamoDB, and API Gateway HTTP API:
module "dynamodb" {
source = "jonmatum/serverless-modules/aws//modules/dynamodb"
table_name = "my-app-items"
hash_key = "id"
billing_mode = "PAY_PER_REQUEST"
enable_point_in_time_recovery = true
enable_encryption = true
}
module "api_gateway" {
source = "jonmatum/serverless-modules/aws//modules/api-gateway"
name = "my-app-api"
vpc_link_subnet_ids = module.vpc.private_subnet_ids
vpc_link_security_group_ids = [aws_security_group.vpc_link.id]
integrations = {
proxy = {
method = "ANY"
route_key = "ANY /{proxy+}"
connection_type = "VPC_LINK"
uri = module.alb.listener_arn
}
}
enable_access_logs = true
enable_xray_tracing = true
}
module "cloudfront" {
source = "jonmatum/serverless-modules/aws//modules/cloudfront-s3"
name = "my-app-web"
enable_logging = true
}A key decision when using API Gateway — the modules support both versions:
| Feature | HTTP API (v2) | REST API (v1) |
|---|---|---|
| Cost | $1.00/million requests | $3.50/million requests |
| VPC integration | Direct to ALB | Requires intermediate NLB |
| Latency | Lower | Higher (extra hop) |
| OpenAPI | Yes | Yes |
| CORS | Built-in | Manual configuration |
| API Keys / Usage Plans | No | Yes |
| Request validation | Limited | Full |
Recommendation: use HTTP API (v2) unless you need API keys or usage plans. It is 71% cheaper with lower latency.
Every module implements AWS Well-Architected Framework best practices. The full document details each decision.
| Pillar | Implementation |
|---|---|
| Security | Encryption at rest/transit, IAM least-privilege, VPC endpoints, WAF |
| Reliability | Multi-AZ, auto-scaling, health checks, DLQ, alarms |
| Operational excellence | Container Insights, access logs, CloudWatch, pre-commit hooks |
| Performance | Fargate compute, VPC endpoints, CloudFront CDN |
| Cost optimization | Fargate Spot, lifecycle policies, VPC endpoints, single NAT for dev |
# Production: Multi-AZ, On-Demand, auto-scaling
module "vpc" {
source = "jonmatum/serverless-modules/aws//modules/vpc"
single_nat_gateway = false # Multi-AZ NAT
enable_vpc_endpoints = true
}
module "ecs" {
source = "jonmatum/serverless-modules/aws//modules/ecs"
enable_fargate_spot = false
enable_autoscaling = true
autoscaling_min_capacity = 2
autoscaling_max_capacity = 10
autoscaling_target_cpu = 70
}# Development: Single NAT, Spot, minimal capacity
module "vpc" {
source = "jonmatum/serverless-modules/aws//modules/vpc"
single_nat_gateway = true
}
module "ecs" {
source = "jonmatum/serverless-modules/aws//modules/ecs"
enable_fargate_spot = true
desired_count = 1
}| Environment | Monthly cost | Configuration |
|---|---|---|
| Development | $70–90 | Single NAT, Fargate Spot, 1 task |
| Staging | $150–200 | Single NAT, On-Demand, 2 tasks |
| Production | $200–400 | Multi-AZ NAT, auto-scaling 2–10 tasks |
Production breakdown: NAT Gateways (2×) ~$65/month, Fargate (2–10 tasks) ~$50–200/month, ALB ~$20/month, DynamoDB on-demand variable.
Each example includes idempotent deployment scripts:
cd examples/ecs-app
./deploy.sh # Initial deployment (Terraform + Docker build + push)
./redeploy.sh # Redeploy after code changes
terraform destroy # Destroy infrastructureModules support idempotent deployments — terraform apply && terraform destroy && terraform apply works without errors.
These modules solve a concrete problem: deploying serverless applications on AWS requires coordinating dozens of resources (VPC, subnets, NAT, ALB, ECS, IAM roles, security groups, CloudWatch) with configurations that must follow security and reliability best practices. Without reusable modules, every team reinvents these configurations — and frequently omits encryption, health checks, or auto-scaling. The collection reduces a production deployment from hundreds of lines of IaC to compositions of 5–10 modules with secure defaults.
Practice of defining and managing infrastructure through versioned configuration files instead of manual processes. Foundation of modern operations automation.
Cloud computing model where the provider manages infrastructure automatically, allowing code execution without provisioning or managing servers, paying only for actual usage.
HashiCorp's Infrastructure as Code tool that enables defining, provisioning, and managing multi-cloud infrastructure through declarative HCL files.
AWS container orchestration service that runs and scales Docker applications without managing the underlying cluster infrastructure.
Serverless compute engine for containers that eliminates server management, allowing Docker container execution paying only for consumed resources.
AWS managed service for creating, publishing, and managing REST, HTTP, and WebSocket APIs that act as entry points to Lambda functions and other backend services.
AWS serverless compute service that runs code in response to events without provisioning or managing servers, automatically scaling from zero to thousands of concurrent executions.
AWS serverless NoSQL database with single-digit millisecond latency at any scale, ideal for applications requiring high performance and automatic scalability.
AWS framework with six pillars of best practices for designing and operating reliable, secure, efficient, and cost-effective cloud systems.
AWS fully managed message queue service that decouples distributed application components, guaranteeing message delivery with unlimited scalability.
AWS pub/sub messaging service that distributes messages to multiple subscribers simultaneously, enabling fan-out patterns and notifications at scale.
Repositories for storing, versioning, and distributing container images, from public registries like Docker Hub to private registries like ECR.