The Silver Lining in the Cloud (Resume Challenge)
Tags: aws, python, serverless, career
Published: 2020-08-07 01:41:00

A few months back, I came across the [Cloud Resume Challenge](https://cloudresumechallenge.dev/) proposed by [Forrest Brazeal](https://twitter.com/forrestbrazeal). It seemed like a good way to practice some hands-on building in the cloud on a real project, so I decided to join the community and work on the challenge.

The details of the Cloud Resume Challenge were as follows:

1.  **Certification**: Your resume has to have the AWS Cloud Practitioner certification on it. This was no sweat, since I already had a few AWS certifications, Cloud Practitioner being one. :white_check_mark:

2.  **HTML**: Your resume has to be written in HTML. :white_check_mark:

3.  **CSS**: Your resume has to be styled with CSS. :white_check_mark:

4.  **Static S3 Website**: Your resume should be deployed online as an AWS S3 static website. I also chose to use a second S3 bucket (www) to redirect back to my naked domain. :white_check_mark:

5.  **HTTPS**: The S3 website URL should use HTTPS for security. I was impressed with how smoothly AWS Certificate Manager and CloudFront made this process work. :white_check_mark:

6.  **DNS**: Point a custom DNS domain name to the CloudFront distribution. This was the first time I got to actually use AWS Route 53 for managing a real domain. Again, smooth sailing. :white_check_mark:

7.  **JavaScript**: Your resume webpage should include a visitor counter that displays how many people have accessed the site, using JavaScript. Not being a person who uses JavaScript a ton, this forced me down a rabbit hole of learning way more JavaScript than I ever thought I'd need (e.g., requests, promises, synchronous, asynchronous), and it was my first spot where I struggled on this challenge. :white_check_mark:

8.  **Database**: The visitor counter will need to retrieve and update its count in a database somewhere. As suggested in the instructions, I used the NoSQL key-value database DynamoDB for this. :white_check_mark:

9.  **API**: Do not communicate directly with DynamoDB from your JavaScript code. Instead, create an API that accepts requests and communicates with the database. I had one small stumbling block related to the Decimal data type in DynamoDB and transforming it back to a JSON response, but as everyone knows, StackOverflow is most definitely your friend. :white_check_mark:

10. **Python**: You will need to write a bit of code in the Lambda function. Once my Python code was working, it was still rather sloppy and monolithic, so I modularized the code so that it would be easier to test in the next step. :white_check_mark:

11. **Tests**: You also need to include some tests for your Python code. This introduced me to the [moto](https://github.com/spulec/moto) library, which allows you to create mock AWS services for testing purposes. I also used the standard unittest module in Python. :white_check_mark:

12. **Infrastructure as Code**: You should not be configuring the DynamoDB table, API Gateway, or Lambda function manually by clicking around in the AWS console. Instead, you should use an AWS Serverless Application Module (SAM) template to deploy these resources using the AWS SAM CLI. After getting over the initial learning curve of SAM, I can definitely see the value that it provides for managing IaC and actually became very comfortable working with it. :white_check_mark:

13. **Source Control**: Create a private GitHub repository for your back-end code. :white_check_mark:

14. **CI/CD Back-End**: Set up GitHub Actions so that when you push an update to your SAM template or Python code, your Python tests get run automatically. If the tests pass, then build and deploy to AWS. I found GitHub Secrets and GitHub Actions to both be pretty intuitive to use. I still had some deployment errors, but they were rather easily fixed. :white_check_mark:

15. **CI/CD Front-End**: Create a second private GitHub repository for your front-end website code, and use GitHub Actions to push any updated code automatically to the S3 bucket where your site assets are hosted. 

16. **Blog Post**: Finally, after much experimentation, having a gazillion tabs open on my browser, and powering through and debugging many different errors along the way, I got to the end of the challenge. Culminating in this post! :tada: :white_check_mark:

Overall, going through the process of this challenge was amazingly valuable. All of the hours spent searching and fixing things were totally worth it, and this was a wonderful learning experience.