I started the Cloud Resume Challenge in March of 2023, but due to circumstances beyond my control, I had to take a hiatus, eventually resuming in August 2023. Thus far, the journey has proven to be exceptionally fulfilling, introducing me to tools and technologies I had yet to explore. My blog on this challenge is a two-part blog series, the first part can be found here.
In the past, I employed a manual approach to deploy application files to AWS S3 after each build, relying on personal console interaction. Although this method is occasionally employed, it isn't typically recommended. In a bid to enhance deployment efficiency, increase deployment frequency, and eliminate manual intervention, I opted to create a Jenkins script designed specifically for deploying the build files. This transition aimed to streamline the process while reducing human involvement.
The Jenkins script I authored was written in a scripted format. This script brought about several key functionalities, including the ability to dispatch Slack notifications regarding the application build status, orchestrate the building of the React application, and effectuate the deployment of the build files to AWS S3. I also implemented a shared library for the Jenkins script. The function responsible for sending the various status messages was written in Groovy and incorporated using Jenkin’s shared library.
From the onset of the project, I decided the AWS infrastructure would be deployed using Infrastructure as Code (IAC). The first Terraform IAC codes I wrote before had CloudFront cache validated, which meant any changes on the build file take a considerable amount of time to get implemented on the Live demo. In order to invalidate the CloudFront cache, I added a new aws_cloudfront_cache_policy
to my CloudFront Terraform script. With this policy, any changes in the application build files are immediately reflected in the CloudFront Live demo.
One important feature of the Cloud Resume Challenge is implementing the visitor’s counter to the website using AWS’s DynamoDB and Lambda function services. I created the DynamoDB table using id
as my key to track the visitor’s view count. AWS Lambda functions can be written in most programming languages. My background in Python made using the language, for writing my visitor count function, an easy choice.
The Python lambda_function
I wrote does four things;
When I tested the function, I encountered a permission error. My Lambda function had no access to my DynamoDB table, so I created a lambdaDynamoRole
to be assumed by my function.
The create role had read and write access to my table. In the creation of my function, I selected the Function URL
checkbox, creating an API URL which I then implemented in my website script.
The trickiest part of this Challenge was implementing the API URL into the React project. As I stated in the first part of the blog, I used a template designed by Sachin Mittal. I have no previous experience working with React, this project presented my first opportunity of modifying a React script.
To implement the views count in the website, after prolonged research I discovered this task had something to do with the application state. So, I wrote an async
function
counterFunction(url)
which takes the API URL as an argument and returns the views count. I used React props
to create a variable that will hold the views count value.
To assign the value of the views count, React’s Promise
was used to resolve the output of the counterFunction(url)
whose output value was reassigned to another variable called count
. The count
variable; a Promise
has a then
method that I used to pass its value to the current state of the application being rendered. Below is the React code I implemented to get it to work.
# JavaScript code to retrieve the views object from my DynamoDB
async function counterFunction(url){
const response = await fetch(url);
const views = await response.json();
return views
}
# This lines of code is implemeted right in the Sidebar Class of my application component
constructor(props) {
super(props);
this.state = {
viewsCount: props.initialValue,
};
}
componentDidMount() {
let count = Promise.resolve(counterFunction(url));
count.then(value => {
this.setState({ viewsCount: value });
})
}
Finally, with my visitors count feature properly working on my website, I pushed the application to my GitHub repo, ran my Jenkins build and everything works just fine in the live demo. At the moment, my Jenkins pipeline needs to be triggered manually because I am using a Vagrant environment which doesn’t allow public access into the environment. The complete codes for this project can be found in this repository. The live demo of the website can be found here.
Thanks for joining me on this journey! Cheers.
Lead image source.