# How I Built an Automated Serverless Resume on AWS (Cloud Resume Challenge)
The Cloud Resume Challenge is a practical exercise in moving beyond tutorials into production-style cloud engineering. It forces you to design, deploy, and integrate multiple AWS services into a single working system.
This project evolved from a manually deployed serverless setup into a fully automated Infrastructure-as-Code pipeline on AWS using Terraform and GitHub Actions.
---
## ποΈ Architecture Overview
The system is fully serverless, globally distributed, and provisioned entirely through Infrastructure-as-Code:
**S3 β CloudFront β API Gateway β Lambda β DynamoDB**
### Core Components
#### 1. Frontend (S3)
- Static resume site built with HTML and Tailwind CSS
- Hosted in a private Amazon S3 bucket
- No direct public access; served via CloudFront only
#### 2. CDN (CloudFront)
- Global content delivery via AWS edge locations
- HTTPS enforced by default
- Aggressive caching for performance optimization
#### 3. Database (DynamoDB)
- Serverless NoSQL table in pay-per-request mode
- Stores a persistent visitor counter (`ID: visitors`)
- Low-latency reads/writes for API interactions
#### 4. Backend (Lambda)
- Python-based AWS Lambda function using `boto3`
- Performs atomic read/increment operations on DynamoDB
- Stateless compute layer triggered via API Gateway
#### 5. API Layer (API Gateway)
- HTTP API with `/counter` POST route
- Proxy integration directly to Lambda
- CORS enabled for browser-based frontend access
#### 6. Infrastructure as Code (Terraform)
- Entire AWS stack defined declaratively in `main.tf`
- Uses `terraform state` to manage resource mapping
- Handles IAM roles, API routes, Lambda packaging, and S3 deployment
#### 7. CI/CD (GitHub Actions)
- Automated deployment pipeline for frontend assets
- Push-to-deploy workflow into S3
- CloudFront cache invalidation after every release
---
## π§ Key Engineering Challenges & Fixes
### 1. Git Push Failure: 100MB File Limit (Terraform Provider Bloat)
While staging the repository, Git accidentally tracked `.terraform/` directories. This introduced a large AWS provider binary (~600MB+), exceeding GitHubβs 100MB file limit.
#### Root Cause
Terraform initializes large provider binaries locally, which can be mistakenly committed if not ignored early.
#### Fix
Even after updating `.gitignore`, the file history still contained the large binaries. A full index reset was required:
```bash
git rm -r --cached .
git reset --mixed <clean-commit-hash>
git add .
git commit -m "chore: clean terraform state and restructure repo"
git push origin main
This removed the cached large files from Git tracking and rebuilt a clean commit history.
2. Migrating to Infrastructure-as-Code (Terraform Import)
A major challenge was converting manually created AWS resources into Terraform-managed infrastructure without duplication errors.
Approach
- Defined equivalent resources in
main.tf - Used
terraform importto map existing AWS resources into Terraform state - Gradually aligned live infrastructure with declarative definitions
This transitioned the system from βclick-opsβ to fully reproducible infrastructure.
3. API Gateway + Lambda Response Handling
Initial frontend integration produced errors like:
Views: undefinedSyntaxError: "undefined" is not valid JSON
Root Cause
HTTP API proxy integration already returns parsed JSON. The frontend incorrectly attempted redundant parsing of response.body.
Fix
const response = await fetch(apiURL, { method: "POST" });
const data = await response.json();
document.getElementById("counter").innerText = data.count;
Removing unnecessary parsing resolved the issue and stabilized the UI.
π‘ Key Takeaways
Automation-first architecture
Shifting from manual deployments to Git-driven Infrastructure-as-Code enables full environment reproducibility in seconds.
IAM least privilege design
Lambda execution role was explicitly scoped to only the required DynamoDB table, minimizing blast radius.
Real-world DevOps friction
The project surfaced production-grade issues:
- Git history cleanup for large binaries
- CORS and API integration debugging
- CDN cache invalidation strategies
- Terraform state management and imports
π Live Project Links
- π Live Site: https://d1l6jcvu4zf64q.cloudfront.net/
- βοΈ API Endpoint: https://t9bxl7c440.execute-api.eu-north-1.amazonaws.com/counter
- π» GitHub Repo: https://github.com/waisyrr/cloud-resum
π Closing
This project demonstrates how a set of core AWS services can be composed into a production-grade serverless system.
The main outcome was not the resume itself, but the operational model behind it: fully automated, reproducible cloud infrastructure built with Infrastructure-as-Code, CI/CD, and stateless compute design.













