A production-grade serverless library search application built on AWS β demonstrating end-to-end Infrastructure as Code, secure CI/CD, and production observability.
LibraryFinder is a cloud-native portfolio project that helps users discover public libraries. It's deliberately scoped to demonstrate production-ready AWS patterns across the full stack β not to ship a feature-complete product.
What this project demonstrates:
- Infrastructure as Code β every AWS resource defined in Terraform, deployable from a single
terraform apply - Serverless architecture β Lambda + API Gateway v2 (HTTP API) + RDS PostgreSQL
- Secure CI/CD β GitHub Actions with OIDC federation, zero stored AWS credentials
- Production observability β 5 CloudWatch alarms on key SLIs, SNS email delivery, verified end-to-end
- Cost discipline β AWS Budget guardrails, RDS stopped when idle
Request path: User β S3 (static frontend) β API Gateway v2 β Lambda β RDS PostgreSQL
Alert path: CloudWatch alarm breach β SNS topic β Email notification
Deploy path: git push β GitHub Actions (OIDC auth) β terraform apply
- Compute: AWS Lambda (Node.js)
- API: API Gateway v2 (HTTP API)
- Data: RDS PostgreSQL
- Frontend hosting: S3 static website
- Networking: VPC, subnets, security groups
- IAM: least-privilege roles per service
- IaC: Terraform
- CI/CD: GitHub Actions with OIDC federation
- Monitoring: CloudWatch alarms + dashboards
- Alerting: SNS β email
- Cost: AWS Budgets
- Backend: Node.js Lambda handler
- Frontend: Static HTML + JavaScript
- Database: PostgreSQL with seeded library dataset
library-finder-aws/
βββ frontend/ # Static site (S3)
βββ backend/
β βββ lambda/
β βββ search-api/ # Main API handler
β βββ db-setup/ # DB bootstrap
βββ terraform/
β βββ phase1-serverless/
β βββ provider.tf
β βββ vpc.tf # VPC + subnets
β βββ security-groups.tf
β βββ rds.tf # PostgreSQL
β βββ s3.tf # Frontend bucket
β βββ lambda-search-api.tf # Search Lambda
β βββ lambda.tf # DB setup Lambda
β βββ github-oidc.tf # CI/CD IAM role
β βββ monitoring.tf # CloudWatch + SNS
β βββ budget.tf # AWS Budget
β βββ variables.tf
β βββ outputs.tf
βββ .github/workflows/ # CI/CD pipelines
βββ docs/
β βββ architecture.svg # Architecture diagram
βββ README.md
- AWS account with appropriate IAM permissions
- Terraform β₯ 1.5
- AWS CLI v2 configured
- Node.js β₯ 18 (for local development)
# Clone the repository
git clone https://github.com/mittal-jn/library-finder-aws.git
cd library-finder-aws/terraform/phase1-serverless
# Set required variables in terraform.tfvars (gitignored)
# See terraform.tfvars.example for the full list
# Deploy
terraform init
terraform plan
terraform applyAfter deployment, confirm the SNS email subscription from your inbox β alarms won't deliver until confirmed.
# Test the Lambda handler locally
cd backend/lambda/search-api
npm install
npm testFive CloudWatch alarms cover the critical SLIs for a serverless API:
| Alarm | Metric | Threshold |
|---|---|---|
lambda-errors |
Lambda Errors (sum) | > 0 per 5 min |
lambda-duration-high |
Lambda Duration (avg) | > 80% of timeout |
lambda-throttles |
Lambda Throttles (sum) | > 0 per 5 min |
api-5xx-rate |
API Gateway 5xx / Count |
> 1% over 10 min |
api-latency-p95 |
API Gateway Latency (p95) | > 2000 ms over 10 min |
All alarms publish to a single SNS topic with email subscription. Pipeline verified end-to-end via direct aws sns publish test.
- OIDC federation β GitHub Actions assumes AWS IAM roles via short-lived tokens; no long-lived credentials stored as secrets
- Least-privilege IAM β separate roles per Lambda, permissions scoped to required actions only
- Private networking β RDS in private subnet, not publicly accessible
- Credential hygiene β
terraform.tfvarsand state files gitignored; secrets passed viaTF_VAR_*env vars - Encryption β RDS and S3 encrypted at rest
Real monthly cost tracks close to $0 when the environment is idle.
| Service | Active Cost | Idle Cost |
|---|---|---|
| RDS (db.t3.micro) | ~$12β15/mo | $0 (stopped) |
| Lambda | < $0.01 | $0 |
| API Gateway v2 | < $0.01 | $0 |
| S3 static hosting | < $0.50 | < $0.50 |
| CloudWatch alarms | ~$0.50/mo | ~$0.50/mo |
| SNS (email) | $0 | $0 |
Cost controls in place:
- AWS Budget at $15/month with email alerts at 80% actual and 100% forecasted
- RDS stopped when not in active development (dominant cost lever)
- Free-tier coverage for Lambda, S3, and CloudWatch basic tier
| Phase | Status | Scope |
|---|---|---|
| 2A β Core infrastructure | β Complete | VPC, subnets, security groups, RDS, S3, IAM |
| 2B β Search API | β Complete | Lambda handler + API Gateway v2 (HTTP API), CORS |
| 3 β CI/CD pipeline | β Complete | GitHub Actions + OIDC federation |
| 4 β Monitoring | β Complete | 5 CloudWatch alarms + SNS + AWS Budget |
- CloudWatch Dashboard β consolidated view of Lambda + API Gateway metrics
- X-Ray distributed tracing β enable on Lambda and API Gateway for request-level observability
- Aurora Serverless v2 migration β eliminate the RDS stop/start pattern, scale to zero
- API Gateway caching β reduce Lambda invocations for repeat queries
- WAF integration β rate limiting and common attack protection
- API Gateway v1 vs v2 metric dimensions differ (
ApiNamevsApiId,5XXErrorvs5xx). Getting this wrong causes alarms to silently never fire β Terraform will accept the config but metrics return no data. - Migrating from Lambda Function URLs to API Gateway solved CORS issues cleanly. Taught me to reason about the request boundary separately from the compute layer.
- OIDC federation is one-time setup complexity for permanent security payoff β worth the extra hour on first config.
- Alarm
ok_actionsare a free built-in test of the notification path β no need to simulate failures to verify the alert pipeline works.
Full-stack application deployed and tested end-to-end:
- Frontend hosted on S3 (static HTML/JS)
- API served by Lambda behind API Gateway v2
- Data stored in PostgreSQL on RDS
- Environment spun down between demos for cost control β available on request
Search by city returns real library data from RDS PostgreSQL via Lambda and API Gateway:
5 CloudWatch alarms monitoring the serverless stack β all healthy:
MIT β see LICENSE.
Mittal Jain
- GitHub: @mittal-jn
- LinkedIn: linkedin.com/in/mittaljain
- AWS Documentation and Well-Architected Framework
- HashiCorp Learn (Terraform tutorials)
- Terraform AWS Provider registry
β Star this repo if you found it useful β feedback and suggestions welcome via GitHub Issues or LinkedIn.

