This repository contains my implementation of the Cloud Resume Challenge (AWS version).
The goal of this project was not just to host a resume, but to design, secure, automate, and explain a real-world cloud architecture using modern AWS and DevOps best practices.
This project focuses on depth of understanding, clean architecture, and production-style decisions rather than just making something “work”.
A serverless web application that:
- Serves a static resume frontend securely via CloudFront + private S3
- Tracks page visits using a serverless backend
- Is fully provisioned using Terraform (Infrastructure as Code)
- Is deployed automatically using GitHub Actions (CI/CD)
The entire stack can be created and destroyed on demand, ensuring low cost and full reproducibility.
Browser
↓ HTTPS
CloudFront (CDN)
↓ (Origin Access Control)
Private S3 Bucket (Frontend)
Browser
↓
API Gateway (HTTP API)
↓
Lambda (Node.js)
↓
DynamoDB (Visitor Counter)
- No public S3 buckets (CloudFront is the only entry point)
- Serverless-first (no EC2, no servers to manage)
- Least-privilege IAM (no wildcard permissions)
- Infrastructure as Code for everything
- Amazon S3 – Stores static resume files (private bucket)
- Amazon CloudFront – CDN, HTTPS, caching, and public access layer
- Origin Access Control (OAC) – Secure CloudFront → S3 access
- Amazon API Gateway (HTTP API) – Public API endpoint
- AWS Lambda (Node.js 18) – Serverless backend logic
- Amazon DynamoDB – Stores and atomically updates visitor count
- IAM Roles & Policies – Least-privilege access for Lambda
- Resource-based Lambda permissions – Allow API Gateway invocation
- Terraform – Provision and manage all AWS resources
- GitHub Actions – CI/CD pipeline for frontend deployment
- Each page load triggers a
GET /countAPI request - API Gateway invokes a Lambda function
- Lambda performs an atomic update in DynamoDB using
UpdateItem - The updated count is returned to the frontend
- Fully managed
- Serverless
- Atomic counters without locks
- No scaling or capacity planning required
- S3 bucket is completely private
- CloudFront accesses S3 using Origin Access Control (SigV4)
- Public access to S3 is blocked at both bucket and account levels
- IAM policies grant only required actions
Direct access to S3 objects returns AccessDenied, which is the expected and correct behavior.
All infrastructure is defined using Terraform, including:
- S3 bucket and bucket policy
- CloudFront distribution and OAC
- DynamoDB table
- IAM roles and policies
- Lambda function
- API Gateway routes, integration, and stage
- Explicit
$defaultstage for API Gateway HTTP API - Dependency management via Terraform references
- Ability to fully destroy infrastructure to avoid cost
- AWS account
- AWS CLI configured (
aws configure) - Terraform v1.x installed
- IAM permissions to create serverless AWS resources
terraform initInitializes providers and prepares the working directory.
terraform validateValidates the Terraform configuration files and checks for syntax
terraform planPreviews all AWS resources that will be created or modified.
terraform applyApplies the Terraform plan and provisions AWS resources.
Triggered on every push to main affecting the client/ directory:
- Checkout repository
- Configure AWS credentials via GitHub Secrets
- Sync frontend files to S3
- Invalidate CloudFront cache
- No manual uploads
- No local AWS credentials required
- Reproducible and auditable deployments
The frontend does not hardcode infrastructure details.
- API base URL is injected via a runtime
config.js - Frontend logic reads configuration dynamically
This decouples frontend code from infrastructure changes and supports future multi-environment setups.
- Designing service-to-service IAM permissions is more important than syntax
- HTTP APIs behave differently than REST APIs (explicit stage matters in Terraform)
- CloudFront should be the public entry point, not S3
- Infrastructure should be easy to destroy if it’s truly owned
- CI/CD should be boring, predictable, and automated
- Designed and deployed a serverless AWS application using CloudFront, API Gateway, Lambda, and DynamoDB
- Provisioned secure cloud infrastructure using Terraform with least-privilege IAM
- Implemented CI/CD with GitHub Actions for automated frontend deployments
- Secured static assets using private S3 buckets and CloudFront Origin Access Control
- Built an atomic visitor counter using DynamoDB UpdateItem operations
This implementation prioritizes architectural clarity, security boundaries, and reproducible infrastructure over feature completeness.
Several production enhancements were intentionally deferred to keep the project focused on core AWS service integration, IAM design, and Terraform-based ownership of infrastructure.
All resources in this project are designed to be ephemeral and cost-safe. The infrastructure can be fully provisioned and destroyed using Terraform,
If you find this project useful or have suggestions for improvement, feedback and discussion are always welcome.
Inspired by the Cloud Resume Challenge (AWS), extended with deeper focus on Terraform, IAM, and production-grade design decisions.
