How I completed the Cloud Resume Challenge in 1.5 weeks
Tags: aws, git
Published: 2023-08-30 21:07:27

I am Jeffrey Dinackus and I completed the Cloud Resume Challenge in 1.5 weeks, if that interests you, read on!

In this article I will discuss what I did, the challenges I faced, and how I solved them as well as my background. 

To learn more about the challenge: https://cloudresumechallenge.dev/

See my project: www.resume.jeffreydinackus.com
Repository(without lambda code, as I fear bad hats could use it against me): https://github.com/JeffreyDinackus/Cloud-Resume-Challenge

When I started the challenge, I already knew about git, HTML/CSS/Javascript, AWS and Python to a working level. I'm no expert by any means. I also held the AWS CCP cert, which is technically a requirement of the project. 

By the end I had created, a html resume styled with bootstrap, hosted the html with S3 and CloudFront for HTTPS, a github actions .yaml file to push my changes directly to S3, created a serverless stack of DynamoDB, Lambda (python), and API Gateway and JavaScript in the browser to interact with the API.

The biggest challenges I faced were getting the CloudFront distribution to work properly with my S3 and Route 53 DNS, and understanding how to access the Dynamo DB through my lambda function along with permissions and security.

In terms of how I actually did it in so short a time, I like to break down my projects into parts and think about how to complete each one the best way and the quickest and what exactly I need to do. I also do not give up on a problem unless it doesn't benefit me to keep going or plans change. 

Now on to the technical stuff.

## CloudFront 

I solved the CloudFront distribution problem through the AWS Wiki and some creative testing with my Route 53. The problem turned out to be that to use CloudFront with S3, you need to specify it in the CNAME in CloudFront, I was using a subdomain of www.resume.JeffreyDinackus.com, so when I added *.JeffreyDinackus.com, and then type in www.Resume.JeffreyDinackus.com, it would time out, I assume because it only goes 1 level down(may be incorrect). I ended up adding *.resume.JeffreyDinackus.com and resume.jeffreydinackus.com which worked. Now my certificate also needed to reflect this, so I provisioned multiple starting with the more restrictive and then moving to wildcards. If I make a second subdomain on my website this may need to be changed in the future but it should be fine for now and I currently have no plans to create more. www.Jeffreydinackus.com is hosted separately on AWS Amplify and has it's own SSL cert provisioned automatically by AWS. 

## GitHub actions

This was a tricky one, as I've only written yaml for my minecraft server in high school. I ended up looking at peoples blog posts who had done the challenge previously and combining a couple of them into one document(a majority of the blog posts are from 2020 - 2021 and GitHub is always changing). I also made sure to utilize GitHub secrets to keep my keys private and also my region. If you don't do this hackers will find your API keys and probably start mining bitcoin on your AWS profile or worse. Expect charges. Make sure to use Checkoutv3 as checkoutv2 is depreciated and will make your action fail. 

## Serverless stack

This is the problem I definitely faced the most time on. I made a AWS Sam CLI template which worked and provisioned resources properly by looking at samples on AWS docs and peoples blogs, but the permissions were always wrong. 

At first it was CORS, which can be fixed by the code on this page, https://stackoverflow.com/questions/31911898/configure-cors-response-headers-on-aws-lambda

You also need to enable CORS in S3 and maybe CloudFront, I don't remember because it was easy to do. 

As long as you include that code in your lambda function, CORS should be enabled in API Gateway and this worked for me. Much easier than dealing with the API Gateway console and adding headers. 

I also had a problem with DynamoDB being references by my lambda function. The way Dynamo does it's schema were foreign to me, my background is MySQL. Adding attributes was a pain and I continued to have problems with my lambda failing to recognize my data. It's acceptable and necessary to have fields with the same name in Dynamo which is weird to me. I ended up getting it working by using the AWS Docs. I imagined NoSQL to be more flexible but I suppose it is optimized for writes not reads. Dynamo also uses a dictionary called Item, which is a dictionary of the schema of the database and you will need to work with it do be able to access the database. Comment below if you need help and I will dig up my code or try to explain.

Make sure to use on demand pricing so you don't get overcharged for capacity you don't use.

There's a AWS Cli command to view dynamoDB schema which I found very useful, but I cannot find it now. Might be worth a try asking ChatGPT if you need it. 

For security, I added the permissions to lambda granularity so a hacker couldn't wreck havoc on my dynamo table. This took me some trial and error to get write, but it needs to be able to get (to view value of page count) and put(so it can add 1 on page reload). 

Hope you enjoyed the article and enjoy the cloud! I hope the project is your first step in a long cloud career!