I Built a Serverless Resume Site on AWS. Here's Everything That Broke Along the Way
After a decade in insurance operations, I decided to make my pivot into cloud engineering official by doing the Cloud Resume Challenge ! I wanted to build it according to real-world best practices, so in addition to the steps the challenge provides, I incorporated a private S3 bucket secured with CloudFront Origin Access Control, a dedicated least-privilege IAM user scoped to only the permissions my CI/CD pipeline needed, and mocked unit tests with moto so nothing touches real AWS resources during testing. The site is live at derekjackson.click . It's a static resume served over HTTPS through CloudFront , backed by a Lambda -powered visitor counter, fully codified in Terraform , and deployed automatically via GitHub Actions . Here's how I built it and, more importantly, everything that went wrong along the way. The Architecture Frontend: S3 stores the static site, fully private with Block Public Access on. CloudFront sits in front of S3, using Origin Access Control (OAC) so CloudFront can read the private bucket. AWS Certificate Manager issues the HTTPS certificate (requested in us-east-1 , a hard CloudFront requirement regardless of where the rest of the infrastructure is deployed.) Route 53 hosts the domain and holds the alias record pointing it at CloudFront. Backend: DynamoDB has a single item, on-demand table holds the visitor count. Lambda (Python) atomically increments that count on every request, avoiding race conditions from concurrent visitors. API Gateway (HTTP API) exposes the Lambda over a public GET /visitor-count endpoint the frontend calls when the page is loaded. Operations: Code is written, stored and edited locally. 2. pytest and moto test the Lambda function against a fully mocked DynamoDB before anything touches AWS. 3.After successful testing, git push commits the code to main initiating the pipeline. 4. GitHub Actions deploys frontend changes to S3 and backend changes to Lambda on every push to main . 5. Terraform codifies and imports all 13 l