A simple, serverless To-Do list API built with AWS services and Terraform. This project demonstrates how to build a complete serverless application using AWS Lambda, API Gateway, and DynamoDB.
- Features
- Quick Start
- Architecture
- API Endpoints
- Setup Instructions
- Available Commands
- Additional Documentation
- Project Structure
- Cost Considerations
- Cleanup
- Learning Objectives
- Next Steps
- Troubleshooting
The application follows a serverless architecture pattern:
- API Gateway: Provides HTTP endpoints for the REST API
- Lambda Function: Contains the business logic for task operations
- DynamoDB: Serverless NoSQL database for storing tasks
- Terraform: Infrastructure as Code for provisioning all resources
- Create new tasks with title and description
- List all tasks (sorted by creation date)
- Delete specific tasks by ID
- RESTful API design
- Serverless and scalable
- Pay-per-use pricing model
Deploy in 3 steps:
# 1. Configure AWS credentials
aws configure
# 2. Deploy infrastructure
./scripts/deploy.sh
# 3. Test the API
curl https://your-api-gateway-url/dev/tasks
Method | Endpoint | Description | Example |
---|---|---|---|
GET | /tasks |
List all tasks | curl https://api-url/dev/tasks |
POST | /tasks |
Create a new task | curl -X POST https://api-url/dev/tasks -H "Content-Type: application/json" -d '{"title": "Task", "description": "Description"}' |
DELETE | /tasks/{id} |
Delete a specific task | curl -X DELETE https://api-url/dev/tasks/{task-id} |
{
"title": "Learn AWS Serverless",
"description": "Build a serverless todo API"
}
{
"tasks": [
{
"id": "uuid-here",
"title": "Learn AWS Serverless",
"description": "Build a serverless todo API",
"completed": false,
"created_at": "2024-01-01T12:00:00",
"updated_at": "2024-01-01T12:00:00"
}
]
}
- AWS CLI configured with appropriate credentials
- Terraform (version >= 1.0)
- Python 3.11+
- S3 bucket for Terraform state (optional but recommended)
aws configure
Or export environment variables:
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_SESSION_TOKEN="your-session-token" # If using temporary credentials
Edit terraform/main.tf
and update the S3 backend configuration:
backend "s3" {
bucket = "your-terraform-state-bucket"
key = "serverless-todo-api/terraform.tfstate"
region = "us-east-1"
}
Option A: Using the deployment script (Recommended)
./scripts/deploy.sh
Option B: Manual deployment
cd terraform
terraform init
terraform plan
terraform apply
After deployment, Terraform will output the API Gateway URL. Use the test script:
python scripts/test_api.py https://your-api-gateway-url/dev
Or test manually with curl:
# Create a task
curl -X POST https://your-api-gateway-url/dev/tasks \
-H "Content-Type: application/json" \
-d '{"title": "Test Task", "description": "This is a test"}'
# List tasks
curl https://your-api-gateway-url/dev/tasks
# Delete a task (replace {id} with actual task ID)
curl -X DELETE https://your-api-gateway-url/dev/tasks/{id}
If you prefer to create the Lambda deployment package manually instead of using the automated script:
# Create the Lambda package manually
./scripts/create_lambda_package.sh
# Then deploy
cd terraform
terraform init
terraform plan
terraform apply
The create_lambda_package.sh
script:
- Zips the Lambda function code and dependencies
- Calculates the SHA256 hash for Terraform
- Places the package in the
terraform/
directory - Excludes unnecessary files (
.pyc
,__pycache__
, etc.)
aws-serverless-demo/
├── terraform/ # Terraform infrastructure code
│ ├── main.tf # Main configuration
│ ├── variables.tf # Variable definitions
│ ├── dynamodb.tf # DynamoDB table
│ ├── lambda.tf # Lambda function
│ ├── api_gateway.tf # API Gateway
│ └── outputs.tf # Output values
├── src/
│ └── lambda/ # Lambda function source code
│ ├── lambda_function.py
│ └── requirements.txt
├── scripts/
│ ├── deploy.sh # Automated deployment script
│ ├── cleanup.sh # Infrastructure cleanup script
│ ├── test_api.py # API testing script
│ └── create_lambda_package.sh # Lambda package creation
├── docs/
│ ├── architecture.puml # Architecture diagram (PlantUML)
│ ├── images/
│ │ └── serverless-todo.png # Architecture visualization
│ ├── architecture-explanation.md # Comprehensive architecture guide
│ ├── makefile-guide.md # Complete Makefile usage guide
│ ├── api-testing-guide.md # Comprehensive API testing guide
│ ├── api-quick-reference.md # Quick API reference
│ └── lambda-package-creation.md # Lambda package documentation
├── Makefile # Common commands
└── README.md
This serverless architecture is designed to be cost-effective:
- Lambda: Pay only for compute time (100ms increments)
- API Gateway: Pay per API call
- DynamoDB: Pay-per-request pricing model
- No idle costs: Resources scale to zero when not in use
To avoid ongoing charges, destroy the infrastructure:
Option A: Using the cleanup script (Recommended)
./scripts/cleanup.sh
Option B: Manual cleanup
cd terraform
terraform destroy
Option C: Using Makefile
make destroy
This project covers:
- Serverless Architecture: Understanding Lambda, API Gateway, and DynamoDB
- Infrastructure as Code: Using Terraform for resource provisioning
- API Design: RESTful API patterns and best practices
- AWS IAM: Role-based permissions and security
- Event-Driven Programming: Lambda function event handling
- NoSQL Database: DynamoDB operations and data modeling
- DevOps Practices: Automated deployment and testing
- Professional Code Organization: Modular structure and best practices
The project includes a Makefile with common commands:
make help # Show all available commands
make init # Initialize Terraform
make plan # Plan Terraform deployment
make deploy # Deploy the infrastructure
make destroy # Destroy the infrastructure
make test # Test the API (requires API_URL parameter)
make package # Create Lambda deployment package
make format # Format Python code
make lint # Lint Python code
make clean # Clean up temporary files
Quick Start:
# Show all available commands
make help
# Deploy the infrastructure
make deploy
# Test the API (replace with your actual API URL)
make test API_URL=https://your-api-gateway-url/dev
# Clean up when done
make destroy
For detailed Makefile usage, see Makefile Guide
For detailed information, see the documentation in the docs/
directory:
- Architecture Explanation - Comprehensive guide explaining serverless concepts and AWS services
- Makefile Guide - Complete guide for using the Makefile commands
- API Testing Guide - Comprehensive guide with curl commands
- API Quick Reference - Quick reference for API endpoints
- Lambda Package Creation - Detailed documentation for the package creation script
Consider extending this project with:
- User authentication and authorization
- Task completion status updates
- Task categories and tags
- Search and filtering capabilities
- CloudWatch monitoring and logging
- CI/CD pipeline with GitHub Actions
- Frontend web application
- Lambda timeout: Increase timeout in
variables.tf
- Permission errors: Check IAM roles and policies
- API Gateway CORS: CORS headers are already configured
- DynamoDB errors: Verify table name and permissions
Check CloudWatch logs for Lambda function debugging:
aws logs describe-log-groups --log-group-name-prefix "/aws/lambda/serverless-todo-api"
Contributions are welcome! Please feel free to submit a Pull Request.
If you encounter any issues or have questions:
- Check the Troubleshooting section
- Review the Additional Documentation
- Open a GitHub Issue
- Start a Discussion
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.