Building a Secure, Scalable Serverless To-Do App with AWS


Introduction
Every developer has that one project that forces them to grow beyond their comfort zone. For me, it was building a secure serverless to-do application from scratch — an end-to-end project that touched every stage of the software development lifecycle.
My goal wasn’t just to build another to-do app. I wanted to prove to myself that I could design, develop, and deploy a full-stack application that followed best practices in scalability, security, and automation.
Why This Project?
I wanted to challenge myself to:
Architect and deploy a serverless backend that is scalable and production-ready.
Build a modern frontend that feels responsive and secure.
Integrate user authentication and authorization using Amazon Cognito.
Implement a CI/CD pipeline with GitHub Actions to automate testing, security scans, and deployments.
Treat security as a first-class citizen by embedding it directly into the development pipeline.
Codebase: https://github.com/VishuPatel-27/serverless-secure-todo-app.git
Architecture at a Glance
The application architecture is fully serverless, built entirely on AWS.
Frontend:
Hosted on Amazon S3, served globally through CloudFront (with HTTPS support).
Built with HTML, JavaScript, and Tailwind CSS.
Authentication:
- Managed by Amazon Cognito, which provides user sign-up/sign-in flows and JWT-based authentication.
Backend:
API Gateway to expose REST endpoints.
AWS Lambda functions for CRUD operations on todos.
DynamoDB as the NoSQL data store, partitioned by
userId
.
CI/CD:
GitHub Actions workflows to build, test, scan, and deploy both frontend and backend.
Integrated security scans (SCA, SAST, IaC).
Flow (User Journey)
User visits CloudFront-distributed frontend (from S3).
Frontend integrates with Cognito for sign-up/sign-in → receives JWT token.
User performs CRUD actions → frontend calls API Gateway with JWT token in headers.
API Gateway validates token with Cognito authorizer.
API Gateway invokes the appropriate Lambda function.
Lambda function queries/updates DynamoDB.
Response is returned to API Gateway → frontend → user.
GitHub Actions pipeline ensures automated deploys and security gates.
Challenges I Faced
Like most real-world projects, things didn’t go smoothly from day one. Here are some of the roadblocks I ran into:
API Data Parsing: At first, API responses were
Response
objects withReadableStream
bodies instead of plain JSON. Debugging this was a mini battle in itself.CI/CD Pipeline Integration: Orchestrating one workflow to handle both frontend (Webpack → S3 + CloudFront) and backend (SAM → Lambda, DynamoDB) deployments was trickier than expected.
Automated Security Gating: Researching and integrating multiple security tools (SCA, SAST, IaC scanning) into GitHub Actions took time — but it paid off in catching vulnerabilities early.
Build & Dependency Management: SAM builds initially caused out-of-memory errors. After digging deeper, I learned about
.samignore
limitations and the quirks ofBuildMethod: makefile
.No Prior SAM Experience: This was my first serious AWS SAM project, and I had to learn its conventions quickly.
CORS & Cognito: Getting CORS right was a puzzle, especially since Cognito by default applies the default authorizer on preflight requests.
CloudFront & HTTPS: I had to use CloudFront because Cognito requires HTTPS callback URLs.
What I Learned
How to think in serverless-first architecture.
The importance of security shift-left — making security checks part of CI/CD, not an afterthought.
Deepened my understanding of AWS SAM, API Gateway authorizers, and CloudFront edge cases.
How to keep a project maintainable by splitting backend/frontend workflows but orchestrating them together.
Improvements I Want to Add
The project is far from “done.” A couple of features are on my roadmap:
Password reset flow for Cognito users.
Todo modification after creation.
More advanced logging and monitoring using CloudWatch.
Closing Thoughts
This project wasn’t just about building a to-do app — it was about building confidence in my ability to design and deploy secure, scalable applications in the cloud.
If you’re starting with serverless, my advice would be:
Expect roadblocks — debugging cloud quirks is part of the journey.
Treat CI/CD and security as integral parts of your design, not add-ons.
Learn by doing — nothing beats hands-on experimentation.
That was my journey of building a Secure Serverless To-Do Application with AWS. If you’re exploring serverless or security in the cloud, I’d love to connect and exchange learnings.
#Serverless #AWS #DevOps #Cognito #CI/CD #Security #GitHubActions #APIGateway #Todo #DevSecOps
Subscribe to my newsletter
Read articles from Vishukumar Patel directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Vishukumar Patel
Vishukumar Patel
Hi there! I’m a DevOps enthusiast, certified in AWS, and passionate about crafting innovative cloud solutions. From designing scalable CI/CD pipelines to deploying microservices on cloud platforms, I’ve immersed myself in transforming ideas into impactful technologies.