DEV Community

Cover image for I Built the Cloud Resume Challenge on AWS — Here's Everything I Learned
Ravjot Duhra
Ravjot Duhra

Posted on

I Built the Cloud Resume Challenge on AWS — Here's Everything I Learned

I'm currently studying for the AWS Solutions Architect Associate (SAA-C03)
and I wanted to go beyond flashcards and practice exams. The Cloud Resume
Challenge by Forrest Brazeal is exactly what I needed — a project that
forces you to use the services you're studying in a real, production-grade
deployment. Here's what I built and what I actually learned along the way.


The Stack

S3 · CloudFront · ACM · Lambda (Python) · DynamoDB ·
API Gateway · Terraform · GitHub Actions

All running on AWS Free Tier. Total cost: $0.

Live site: https://d19mfjmr0dtnqm.cloudfront.net
GitHub: https://github.com/RavjotD/cloud-resume-challenge-aws


Week by Week

Week 1–2: S3 + CloudFront

Started by writing my resume in plain HTML and CSS, deploying it to an
S3 bucket with static website hosting enabled, and putting CloudFront
in front of it for HTTPS and global edge caching. The moment I opened
that CloudFront URL and saw my resume load over HTTPS from a CDN was
the first real "I built this" moment.

One thing I didn't expect — S3 defaults to blocking all public access.
You have to explicitly unblock it and apply a bucket policy. AWS makes
you opt in to public exposure rather than opt out. Smart default,
confusing the first time.

Week 3: DNS

Skipped the custom domain step. Route 53 isn't in the free tier and
I didn't want to buy a domain just for a portfolio project. The
CloudFront URL is perfectly functional for what this project needs to
demonstrate. I'll add a custom domain when I'm hosting real client
infrastructure on this account.

Week 4: Lambda + DynamoDB

This is where the project gets interesting. I wrote a Python Lambda
function that reads a visitor count from DynamoDB, increments it, and
returns the updated value. Then I invoked it from the CLI and watched
the count go from 0 to 1 to 2 to 3 in real time.

The IAM Role setup here is directly from the SAA-C03 curriculum —
create a role, define a trust policy that allows Lambda to assume it,
attach least-privilege policies. Doing it by hand makes it click in
a way that reading about it never does.

Week 5: API Gateway

Wired Lambda to a public HTTP endpoint using API Gateway so the
browser can call it. Straightforward setup — create the API, create
the integration, create the route, deploy a stage.

Then spent way too long debugging CORS. Short version: API Gateway
was stripping the CORS headers that Lambda was correctly returning.
The fix was updating the API's CORS configuration to explicitly allow
my CloudFront origin. The debugging process — browser console, curl
with verbose headers, Lambda invocation logs — taught me more about
how HTTP actually works than any course section on networking.

Week 6: Terraform

This was the week everything changed. I rewrote every resource I had
built manually — S3 bucket, CloudFront distribution, DynamoDB table,
Lambda function, IAM role, API Gateway — into Terraform .tf files.

The moment I ran terraform plan and saw "No changes. Your
infrastructure matches the configuration" was genuinely satisfying.
Everything I had built over 5 weeks was now codified. Someone could
clone my repo, run terraform apply, and have the entire stack
rebuilt from scratch in under 2 minutes.

I also had to import existing resources into Terraform state rather
than destroy and recreate everything. Learning the difference between
terraform import, state management, and drift detection was an
unexpected but valuable deep dive.

Week 7: GitHub Actions

Added a CI/CD pipeline that triggers on every push to main.
Two jobs run in sequence — first the test job runs my Lambda unit
tests, and only if they pass does the deploy job run, uploading the
HTML to S3 and invalidating the CloudFront cache.

First successful pipeline run completed in 6 seconds. From that
point on I never manually ran an aws s3 cp command again.

Week 8: Tests and Documentation

Wrote Python unit tests for the Lambda function using unittest and
mocking the DynamoDB table with unittest.mock. Four tests covering
the counter increment logic, status codes, CORS headers, and
DynamoDB being called correctly.

Built the architecture diagram in draw.io and added it to the repo.
Wrote this post.


The Hardest Part

CORS. It's always CORS.

The counter wasn't loading on the live site. No errors in the browser
console, just a dash where the number should be. I opened the Network
tab — the API request wasn't even showing up.

Traced it step by step. Manually ran the fetch in the browser console
— it returned {count: 14} perfectly. So the API worked. The
JavaScript was correct. But the live page showed nothing.

The issue: CloudFront was caching a stale version of the HTML. I had
two CloudFront distributions — created one accidentally during
earlier testing — and I was invalidating the wrong one the whole time.
Found it by listing all distributions from the CLI and comparing the
domain names.

That kind of debugging — ruling out code, ruling out the API, tracing
the exact cached response — is exactly the thinking a solutions
architect needs. The challenge put me in a position where I had to
use it.


What I Actually Learned

Studying for the SAA-C03 teaches you what the services are. Building
this project teaches you how they fit together and where they break.

I now understand why you'd put CloudFront in front of S3 instead of
exposing S3 directly. I understand why Lambda needs an IAM Role
rather than hardcoded credentials. I understand why Terraform state
matters and what happens when it drifts. I understand why tests need
to run before deployments, not after.

None of that comes from flashcards.

What's Next

  • AWS SAA-C03 exam — June 2026
  • Azure version of the Cloud Resume Challenge — same project rebuilt on Azure Blob Storage, Azure CDN, Azure Functions, and Cosmos DB
  • One Terraform codebase deploying to both clouds
  • One GitHub Actions pipeline deploying to both environments

The multi-cloud version is the portfolio piece I'm working toward.
When it's done I'll write about that too.


If you're studying for a cloud certification and haven't done a
hands-on project yet — start the Cloud Resume Challenge. The gap
between knowing a service and deploying one is bigger than you think,
and closing that gap is the whole point.

Top comments (0)