Continuous Deployment with AWS Code Pipeline, React JS, and s3

Alexzander Flores
8 min readJul 12, 2020

Continuous deployment is a fantastic system to automatically deploy your application to a production environment. In this article you’ll learn how to set up a CD pipeline to automatically deploy a React JS application.

Corresponding video tutorial.

Prerequisites

Before you start you’ll need a React JS application with a Github repository, and an Amazon Web Services Account account. If you do not have a React application you can easily make one using create react app.

AWS Services

In this article I’ll be using three different AWS services:

  • S3 — Simple storage service, this will hold your React app’s files and will act as a static website host.
  • Code Pipeline —This is a sub-service of AWS Developer Tools and will allow you to configure and control your CD workflow.
  • Code Build — Another sub-service of Developer Tools, this will automatically build your code into a production state ready for deployment.

Pricing

The services used here are very inexpensive. S3 will charge $0.023 per GB, Code Pipeline will charge $1 per month per active pipeline, and Code Build charges $0.005 per build minute. You can find more information here:

Step 1 — Setting up your s3 bucket

First you need to create an s3 bucket and configure it to host static websites. If you already have this setup then you can skip to step 2.

After navigating to the s3 console you’ll want to click on the “+ Create Bucket” button shown here:

create s3 bucket button

After that you’ll be prompted to enter some basic information about your bucket. The only thing you need to do here is enter a name and click on “Create” at the bottom left of the popup. Keep in mind that s3 bucket names must be globally unique, so you’ll need to enter a name that no one else has used.

Creating a s3 bucket

Now you can click on your s3 bucket to navigate into it. It’s now time to configure it to host static websites correctly.

The first step is to tell s3 that this bucket should host a static website. To do that you can go to the “Properties” tab, select “Static website hosting,” and select “Use this bucket to host a website.” From there enter “index.html” into both the index and error document fields and then click “Save.” Your window should look like this:

Configuring s3 to host a static website

Next you want to allow public access to your s3 bucket. For security reasons s3 will automatically block all public access. To disable this, navigate to “Permissions,” by default you should be at the “Block public access” tab. On the right is an edit button, and after clicking you can uncheck “Block all public access” on the left. Your screen should look like this:

Allowing all public access to your s3 bucket

Now save the settings with the “Save” button on the right. Next enter a bucket policy to allow each of your files to be read correctly. Navigate to the “Bucket Policy” tab and copy/paste this policy:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::YOUR_BUCKET_NAME_HERE/*"
}
]
}

Replace “YOUR_BUCKET_NAME_HERE” with your actual bucket name. My s3 bucket is named “cd-medium-article” so my working policy would be:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::cd-medium-article/*"
}
]
}

The final step in setting up your s3 bucket is to enable CORS. To do that simply navigate to the “CORS Configuration” tab and paste in the following script:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>

There’s nothing to change here. Simply click on the save button and you’re done configuring your bucket!

Step 2 —Setting up AWS CodePipeline

You should have noticed that you haven’t uploaded your React app to your bucket yet, and you won’t be doing that manually. By the end of this article you’ll have CodePipeline deploying your app to s3 automatically. Before you get started let me explain the steps CodePipeline will take to perform this task.

First you will tell CodePipeline where your code repository lives. This tutorial assumes you’re using Github. Now that CodePipeline knows of your repo and the branch you want to listen to, it will utilize Github webhooks to listen for changes on that branch.

When a change is detected in the branch, it will automatically pull your code to a server and attempt to build your code into a production-ready state. You won’t have to manually setup the server at all, just specify a few details such as the operating system.

If the build is successful then the code will be deployed to your s3 bucket. At this step your website is public and the job is done! So let’s get started.

Creating your pipeline

Navigate to the CodePipeline dashboard and click the orange “Create pipeline” button to get started. From there you can enter the name of your pipeline. For simplicity, I’ll be naming mine the same thing as my bucket: “cd-medium-tutorial” and clicking on the “Next” button.

Naming your AWS CodePipeline

Now add your “Stage Source.” This is telling CodePipeline where your repo lives. After selecting Github you will be prompted to login with your Github account. From there select your repo and your branch. It should look like this:

Specifying what github repo and branch CodePipeline will listen to

Adding a build stage

Next you have to configure AWS CodeBuild, which is another service that handles building your code. You want to select AWS CodeBuild. You’ll be promoted to create a project with the “Create project” button. Your screen should look like this:

Selecting AWS CodeBuild

Clicking “Create project” will open a new window. This is where you can specify the operating system for the build server, but first you need to specify a name. Mine is “cd-medium-tutorial.”

Under “Environment” I would suggest using “Amazon Linux 2” with a standard runtime and the “x86 3.0 image.” My page looks like this:

Configuring the build server operating system

Use the default settings for everything else. Scrolling down you’ll find the “Continue to CodePipeline” button which will create the project and close the window.

Select your s3 bucket

You’re almost done. The next step is to tell CodePipeline where your production code should be deployed. Simply select the s3 bucket you created in step 1, and make sure you check “Extract file before deploy.” Without this your code will be in a zipped file that cannot be read by your website visitors. My page now looks like this:

Specifying the s3 bucket to use

Finally you will be in a review page. Simply scroll down and click on “Create Pipeline.”

You will automatically be sent to your pipeline’s progress page. Here you can watch what it is doing in real time. It will automatically try pulling from your repository and start building your code; however, this will fail. We’re missing one last step, that is configuring our “buildspec.yml” file which tells our build server what to do.

After your project initially fails to build you should see a screen like this:

Our first build failed within CodePipeline

Clicking on the highlighted ”Details” link will provide some information into what went wrong. Here we see what I previously mentioned. The “buildspec.yml” file does not exist yet.

Our buildspec.yml file does not exist

In your project, create a new file called “buildspec.yml”. Inside the file paste the following configuration:

# Specifies what build spec version this file is.
# This helps AWS CodePipeline parse the file correctly.
# Keep this at 0.2
version: 0.2
# We can listen for specific phases and execute commands per phase.
phases:
# The build server won't have access to our node_modules folder
# This is because we have it inside of our .gitignore file
# To give our build server access, we can simply run "npm install"
pre_build:
commands:
- npm install
# Now we want to actually build our React app
build:
commands:
- npm run build
# Artifacts will specify what files will be uploaded to s3
# This will include all files within the "build" folder
artifacts:
files:
- '**/*'
discard-paths: no
base-directory: build

This configuration should be good to go and won’t require any modifying. You can learn more about how to edit the fine details in the build spec documentation.

Now push this file to your Github repo, which will then cause CodePipeline to automatically pull your code, build it, and deploy it. This time CodeBuild will know what to do and shouldn’t fail. You can use whatever GUI software you prefer; however, I prefer to use the command line:

Pushing our new buildspec.yml file to our master branch

CodePipeline will automatically detect the changes and will attempt the entire process again. After waiting a few minutes you should see all stages were successful:

All three of our stages were successful

Navigating back to s3 we see the bucket has been filled with the production-ready files as expected:

Our Continuous Deployment system worked!

Finally, go into the “Properties” tab and then “Static website hosting.” Click on the URL to navigate to your own React app. Mine is http://cd-medium-article.s3-website-us-east-1.amazonaws.com. Your deployment worked successfully!

--

--

Alexzander Flores

Developer since 2008. I now create programming tutorials to help people learn the way I did.