- About the project
- My suggestions before getting started
- How much time I spent
-
Reflection
- Project Architecture
- DynamoDB
- API Gateway
- Security
- Git Repo
- More to come
About the project
Cloud Resume Challenge is a project designed to help you get started in the Cloud field if you aspire to become a Cloud/DevOps engineer. The challenge emphasizes real-world experience, and the end goal is to build something you will actually use—not a toy project.
The project itself is a resume website with a page view counter.
You can learn more on the official site and also here, where the creator explains the motivation and goals behind the challenge in more detail.
My suggestions before getting started
If you have limited time and want some practical advice before starting, here are my two cents:
- You can skip the HTML/CSS part. It doesn’t really matter what the site looks like before you put it on your resume. The real value lies in the cloud architecture and implementation.
- If you’re not very familiar with AWS (or the cloud provider you choose), start with the web console instead of Infrastructure as Code (IaC). This allows you to move faster and get a working demo early. When you later switch to IaC, you’ll better understand which configurations were implicitly handled by the console.
- Be conservative with the time you spend on each topic. There’s a lot to cover in this project, and there’s always more to explore. Focus on understanding the overall architecture rather than getting stuck in low-level details.
How much time I spent
I was a frontend engineer transitioning into DevOps. I spent less than a week on this challenge, completing all requirements on the website.
To be honest, the absolute amount of time spent is meaningless. It correlates with how deep someone wants to go and how comprehensive their solution is. Instead, here’s the rough ratio of time I spent on each part:
- HTML/CSS: I used Next.js to build a static site and typed in some basic content, so this took almost no time—around 0–1%.
- Web console setup: By this, I mean creating a fully working demo using the AWS console. This took about 30% of the time, including learning new concepts like API Gateway and Lambda.
- IaC + CI/CD: This took around 50–60% of the time, which I did not anticipate. CI/CD involves a lot of trial and error, and IaC introduced unexpected issues due to hidden configurations created by the web console.
- Blog writing: The remaining time (~10%) was spent on reflection. In my opinion, this is actually the most important part.
Reflection
Spoiler alert: Please stop reading if you haven’t completed the challenge yet, as I’m about to reveal my solution.
Project Architecture
The domain name (janice-zhong.com) is resolved into an IP of a CloudFront distribution, which is connected to a S3 bucket with static hosting. The S3 displays the website content which involves calls to API Gateways that trigger lambda functions to read from and write into a DynamoDB.
Two TLS certs are provisioned in the us-east-1 region for CloudFront and in the apsouth-east-2 region for the API Gateways.
Lambda Function
Lambda is a managed compute service that allows you to run functions on AWS without managed servers. The important point to note is that each Lambda function should be idempotent, which means running your function multiple times should always result in the same outcome. Lambda supports concurrent invocations where each invocation will start with a fresh state, you should assume no state persisting between invocations.
DynamoDB
DynamoDB provides serial writes at the item level
DynamoDB is where I made my first mistake. I thought concurrent Lambda functions will incur race conditions on writes to DB when updating the same record. Therefore, I started with inserting one record per page visit and counting the total number of records.
This approach quickly became problematic because Scan operations in DynamoDB are O(n), which is inefficient for a simple page view counter. Later, I discovered the following:
DynamoDB provides serial writes at the item level by default.
Prevent throttled concurrent writes via client retries
DynamoDB functions based on RCU (Read Capacity Unit) and WCU (Write Capacity Unit). There is a cap to how many concurrent reads/writes per second you can have. The on-demand capacity mode provides 4000 writes/second. Once this cap has been reached, DDB returns a ProvisionedThroughputExceededException error which you can use to attempt retries on the client side.
API Gateways
I'm going to omit details here because the article will get way too long if I covered every topic in depth. I just want to highlight about throttling in API Gateways.
API Throttling
During development, I noticed there were many bot traffic to my CloudFront, which alarmed me to set up throttling in API.
API Gateway throttling can be applied at multiple levels: account (default), stage, and route.
I had applied throttling at the stage level and set burst to 50 and limit to 200. More advanced per IP throttling can be achieved via WAF.
Terraform (IaC)
Remote State + Locking
State should not be committed to VSC to avoid credential leaks and state corruption. Therefore, I initially kept state stored in S3 and later migrated to HCP terraform.
Always pin versions
Always pin provider and module versions to avoid unexpected breaking changes caused by upstream updates.
Use HCP Terraform for automated terraforming (CI/CD)
HCP Terraform offers audit logs, manual approval workflows out of box, without extra configurations compare to GitHub Actions. This significantly reduces operational overhead for Terraform-based CI/CD.
Security
OIDC
OpenID Connection allows GitHub workflows to access AWS using short-lived credentials. GitHub assumes an IAM role defined in your account to perform actions on your behalf. This approach improves security by eliminating long-lived access keys stored in GitHub secrets and reduces the operational burden of credential rotation.
TLS
TLS are used to encrypt traffic between clients and servers. Two TLS certs are provisioned in the us-east-1 region for CloudFront and in the apsouth-east-2 region for the API Gateways.
Adding Human Verification Process
The volume of bot traffic raises concern that legitimate human users would be blocked due to these limits I set. To address this, there are two options:
- CloudFront + AWS WAF. Native AWS solution but comes with some costs. The managed bot control rule group costs:
$10 per month (prorated hourly). Includes processing the first one million web requests of each month. Includes analysis of CAPTCHA and challenge attempts.
A tutorial can be found here.
- I plan to integrate Cloudflare Turnstile which serves the same purpose but free.
Git Repo
- Frontend: https://github.com/qianzhong516/janice-zhong
- IaC: https://github.com/qianzhong516/janice-zhong-iac
More to come
Here I've just got basic workflows running, and I'll be going through the cloud resume challenge book next to implement optional add-on challenges.
Stay Tuned and til then.

Top comments (0)