This is the second part of a series of blogs about the platform management of a React Application infrastructure by adding a continuous deployment component to the earlier infrastructure. In an earlier article, I wrote about how a private react application infrastructure can be deployed with Terraform code. Now, we will explore this further by building a deployment pipeline using AWS CodePipeline.
Let’s assume that the source code of the React web application is hosted on GitHub. Using the GitHub connections feature of AWS CodePipeline, we can authorize the third-party provider to work with AWS resources to establish integration between the two.
What is Continuous Deployment?
As defined in the AWS Well-Architected Framework, Continuous Deployment is the automated deployment to production, which is dependent on results from testing and building. Every time a build and all the tests occur with no errors or failed tests, the code is deployed automatically.
Adding automation to deployment keeps the process simple. DevOps Engineers don’t have to manually trigger commands to deploy the latest changes to the application code. As all automations go, we need to always add extra precautions especially when doing deployments to the production environment. Adding simple tests and approval stages can further improve and secure the pipeline and add safeguards to the automation.
Build a Sample React Application for Deployment
To test the deployment pipeline that will be created, we need to have a sample react application to be deployed. Run the following command npx create-react-app sampleapp to create a sample react application in your working directory. The create-react-app command creates a new directory in the current folder and generates the initial project structure of the web application.
$npx create-react-app sampleapp Creating a new React app in /Users/karina.alvarado/Workspace/tutorials-dojo. Installing packages. This might take a couple of minutes. Installing react, react-dom, and react-scripts... Inside that directory you can run several commands: npm start Starts the development server. npm run build Bundles the app into static files for production. npm test Starts the test runner. npm run eject Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can't go back! We suggest that you begin typing: cd sampleapp npm start Happy Hacking!
After the command execution is completed, follow the suggestion by navigating to the sampleapp directory, then start the application with npm start. Once the application is compiled, you should be able to access the application locally via http://localhost:3000/.
$npm start Compiled successfully! You can now view sampleapp in the browser. Local: http://localhost:3000 On Your Network: http://192.168.123.35:3000 Note that the development build is not optimized. To create a production build, use npm run build. webpack compiled successfully
This initial project is focused only on writing and running the sample code locally within the machine. Once the application is ready to be deployed to production, we can use the npm run build command as recommended. We can check-in this code in a third-party source code repository like Github.
Create the Deployment Pipeline and Test
Now that we have the application ready, let us create the deployment pipeline in AWS CodePipeline. AWS CodePipeline is an automation tool for the continuous delivery of code. It is a fully managed continuous delivery service that automates release pipelines for fast and reliable application and infrastructure updates. AWS CodePipeline works with other services like AWS CodeBuild and AWS CodeDeploy.
The diagram below shows how the pipeline will run. AWS CodePipeline can be set up to detect changes in the source code repository and start the pipeline based on this change. Using AWS CodeCommit, a connection can be set up to access the source code in GitHub. Then, AWS CodeBuild can run specific commands or build actions to compile the code to a runnable application. AWS CodeDeploy can then move the runnable code to the infrastructure serving the application, such as Amazon S3.
In creating a pipeline, navigate to the AWS CodePipeline service in the AWS Management Console and create a pipeline. In choosing the pipeline type, consider the features of each type as well as its pricing. The pipeline name cannot be changed after the pipeline is created. For the first step, we will leave most options to their default values.
For step 2, we can define the source provider of the pipeline. Since the source code is in GitHub, we will select this option. Other providers can be AWS CodeCommit, Amazon ECR, S3, Bitbucket, GitHub Enterprise Server, GitLab, and GitLab self-managed. For GitHub, there are two options: Version 1 and Version 2. Version 1 makes use of OAuth to access the GitHub repository, but is not a recommended method. For version 2, a connection is created using GitHub Apps and is the recommended method of establishing a connection.
To set up a new connection, you can click on the Connect to GitHub button. This will open a pop-up wizard that can easily provision the connection needed by the pipeline.
Additionally, you can select All or specific repositories to allow AWS CodePipeline access.
Other configurations can also be finalized in step 2, such as repository name, pipeline trigger, branch name, and the output artifact format.
Step 3 (Build stage) will be skipped for now since the files are being compiled locally.
Since we already skipped Step 2 (build stage), there will be a warning on the next step that it cannot be skipped. Pipelines require at least two stages to be created so the deploy stage needs to be configured along with the source stage.
The last step will allow you to review the pipeline before it is created.
Also, ensure that the S3 bucket where the app will be deployed has ACLs enabled. This will allow other resources, such as GitHub, to upload to the bucket.
Once this is done, you can try to add a change to the repository in GitHub and see if the pipeline gets triggered automatically. Once the pipeline runs, you should be able to see the objects get updated in the configured S3 bucket. Since the private react application is not configured with caching, we should expect to see the changes reflected automatically to the private domain instantly.
In the future, when the app is then deployed to a public domain with a CloudFront, we would need to set up some minor code to invalidate the CloudFront cache if we want the changes reflected automatically after deployment. This can also be done using the aws-cli code below:
aws cloudfront create-invalidation --distribution-id --paths {CLOUD_DISTRIBUTION_ID} "/*"
Final Thoughts
Deploying using AWS CodePipeline is just one way to automate CI/CD pipelines. Other popular tools like Jenkins and GitHub actions can also be utilized to compile code and deploy to various AWS resources like EC2 and S3. We will explore this further in another article of this series including deploying the actual infrastructure of the application accessible via a public domain.
References:
https://wa.aws.amazon.com/wat.concept.continuous-deployment.en.html