Intro 😎
In July 2022 I came across the cloud resume challenge by Forrest Brazeal shortly after completing my Cloud Engineer Certification by Google Cloud. The challenge was forwarded to me by mentor Martin and immediately after having an overview of the tasks I knew the challenge was good enough to piece together all I had learned about GCP.
The Resume challenge itself is simple but enables one to stitch together different functionalities of the cloud and come up with a complete workflow of building a static website which is fully hosted on cloud resources. Below is how I did the challenge:
1. Certification 🌱
The challenge required one to have at least completed Google Cloud Digital Leader by Google. Fortunately I had completed Associate Cloud Engineer by Google early July 2022 and I was comfortable building and hosting applications on GCP.
2. Static Website 🎯
The challenge prompted one to write a static site for their resume in HTML & CSS. This was a quick task for me having done a bit of systems development early on in my career, picked up a template online for the look and feel of the site and created custom CSS to make it look better.
3. Site Hosting 👨🏽💻
The static site (Resume) is supposed to be hosted on Google Cloud Storage and use a cloud load balancer for traffic flow. I used GCP storage bucket to host the site while Cloud Load Balancing via HTTP(S) Load Balancer on GCP.
- bucket creation config
resources:
#site bucket
- name: resume.hexorsec.com
type: gcp-types/storage-v1:buckets
properties:
zone: us-central1-f
website:
mainPageSuffix: index.html
notFoundPage: index.html
iamConfiguration:
uniformBucketLevelAccess:
enabled: true
labels:
app: davisresume
- HTTPS certificate
# Put the bucket as a backend service
- name: davis-resume-backend-bucket
type: gcp-types/compute-v1:backendBuckets
properties:
bucketName: $(ref.hexorsec.resume.com.name)
description: Backend bucket for the CDN
enableCdn: true
# Create an HTTPS certificate
- name: davis-resume-https-cert
type: gcp-types/compute-v1:sslCertificates
properties:
type: MANAGED
managed:
domains:
- $(ref.resume.hexorsec.com.dnsName)
4. DNS 🌍
The site is supposed to be pointed to a custom DNS domain name. My domain is already registered on Godaddy and I had just to add an entry for the site. Using the IP address of the Load balancer I created an entry for my resume.
5. Visitor Count 🌏
The challenge prompted one to have a section on the site for number of visitors who visit the site. For this I wrote a simple JavaScript code to fetch JSON content from endpoints and update visitor count on my site.
Firestore
I used Firestore to store and update visitor count object on the site. The database is automatically created by a script when the first visitor reaches the website.
API
The communication between JavaScript code and database is managed by a cloud function on GCP which I created. The function depends on HTTP triggers to invoke an event. The function:
- reads the visitor count from firestore database
- increments it by one
- saves it to the database
- returns the value to the client.
6. Python & Tests 🧩
The challenge prompts us to use python to write the serverless function and then perform some tests on our written code.
For this I used Python3.6 to write the serverless function and the communication between code and the backend db uses the google-cloud-firestore Python library.
7. Tests & Security 🎳
I used Pylint to perform basic test on the code and for the security bit I used snyk SCM to check for vulnerabilities within my code and it's dependencies.
8. IAC, CI/CD & Source Control 🎮
The challenge goes a head and prompt us to do a bit of IAC for automation purposes between the function, firestore and API gateway. The IAC allows one to replicate and do updates easily on the infra being provisioned. I opted to go with Deployment Manager as is an easy way to do quick deployments.
Static Site Syncing
steps:
# Copy the Site content to a GS bucket
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:latest'
id: Sync the website content
args: ['gsutil', '-m', 'rsync', '-r', 'site/', 'gs://resume.hexorsec.com']
Pylint Scanning
steps:
# Pylint SAST
- name: python:3.6
id: Check the python package
entrypoint: 'bash'
args:
- '-c'
- |-
pip install pylint
pip install -r scripts/visitor_count/requirements.txt
pylint scripts/
Infra as Code
# Deploy
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:latest'
id: Deploy the infrastructure
entrypoint: 'bash'
args:
- '-c'
- |-
apt install -y zip
pushd scripts/visitor_count
zip -r ../visitor_count.zip .
cd ..
file_name="count_$(md5sum visitor_count.zip | awk '{print $1}').zip"
mv visitor_count.zip ${file_name}
gsutil cp ${file_name} gs://hexorsec-XXXX-YYYYYYY
popd
gcloud deployment-manager deployments update resume-xxx-depl
Cloud Build
For the build I created two triggers for Infra and static site. With the two build triggers once changes are made to github and action is triggered for syncing and pushing changes.
9. Blog Post 🎲
Finally the challenge prompted one to create a blog post describing the entire process of the challenge. Here is the post for that :)
Outro 🙏🙏
Going through the challenge is one of the best things have done after acquiring the associate cloud engineer cert from google. The entire process showed me how things work in the cloud and how use-cases can be created in such scenarios. I'm so grateful to Forrest Brazeal 👏 for setting up such a great challenge and my Mentor Martin 🫡 for pointing me to such amazing resource for learning.
Top comments (2)
Nice work do u have github page?
Yes I do. But it's private.