Deploy a ReactApplication to AWS S3 and Cloudfront using AWS CodePipeline

Pranita Gughane
8 min readAug 31, 2023

--

In this article, we will look at how we can deploy our webapp to AWS S3 with AWS Cloudfront as our CDN. We’ll look at a simple way to automate our deployments as well.

Prerequisites:

1 ) Set Up an EC2 Instance

  • Log in to your AWS Management Console.
  • Navigate to the EC2 dashboard.

Once the user is connected to the EC2 instance use the following command to get the apt packages updated:

apt-get update

After that install the curl to create React application on the Nginx server by using the following command:

sudo apt-get install curl

After that, use curl to download NodeJS using the following command:

curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -

After the downloading is completed, install the NodeJS using the following command:

sudo apt-get install -y nodejs

Create the application inside the folder using the following command:

npx create-react-app my-app

Use the following commands to start the npm and run the React application:

cd my-app
npm start

The app starts running in the development mode and is served at http://localhost:3000/

Note: 3000 port should be opened in the security group of your EC2 instance.

When you’re ready to deploy to production, running npm run build will create an optimized build of your app in the build folder.

 npm run build

And that’s it! Our Reactjs build production is now ready!

The build directory containing the production build is created within the root project folder.

Let us run the app in production mode. Run the following command to serve the build version in a static server.

npm install -g serve
serve -s build

Create s3 bucket

Let’s create a new S3 bucket

For now, we can just enter our bucket name and leave everything as default

Enable static hosting

Here, we will enable hosting which is present under the Properties tab

Create IAM Role for s3 and cloudfront

Let’s navigate to our AWS Management Console and search for IAM service. Now create a new role for s3 and cloudfront:

Create an IAM role that provides permissions for CodeBuild to access your S3 bucket and read your GitHub repository. Attach policies like AmazonS3FullAccess and CloudfrontFullAccess.

Install AWS CLI

We can install AWS CLI from docs here

apt install awscli
aws configure

Creating AWS access keys involves using the AWS Identity and Access Management (IAM) service. Access keys consist of an Access Key ID and a Secret Access Key, which are used to authenticate programmatic access to your AWS resources.

Access keys are sensitive credentials that should be kept secure. Do not share them openly. If you ever suspect the keys have been compromised, you can delete them and generate new ones.

aws configure
AWS Access Key ID [None]: ***************
AWS Secret Access Key [None]: **************
Default region name [None]:
Default output format [None]:

After configuring the AWS CLI profile, you can confirm that the profile is working by running this command below in PowerShell.

aws s3 ls

The command above should list the Amazon S3 buckets that you have in your account.

Great! seems like our build was synced with our S3 bucket

npm run build && aws s3 sync build/ s3://my-app-reactbuild

Cloudfront

Let’s connect our Cloudfront with our S3 endpoint. If you’re not familiar with Cloudfront, it’s a content delivery network (CDN) that delivers our data (images, videos, API’s, etc.) globally (based on customer’s geographical location) at low latency, high transfer speeds.

Let’s create a Cloudfront distribution

After a few minutes, your distribution would be deployed and you should be able to access your content at distribution DNS!

Invalidation

When we re-deploy or sync our updated build we need to also create an invalidation rule which basically removes an object cache before it expires. This can be really important when serving updates to your web app

aws cloudfront create-invalidation --distribution-id E2R4D1DA76861U --paths /*

Note: Here, we just invalidate * all objects for simplicity, but you might want to customize this depending on your use case

Create a CodePipeline using Github, CodeBuild

As part of this guide, we will be using CodePipeline to automate our release process. The release process will get triggered whenever there is a code change, this is really good as it’ll let us rapidly deliver software. At present, there are three available approaches:

  • AWS Management Console
  • AWS CLI
  • AWS SDKs

For the purposes of this guide, we will use the management console.

Step 1: Choose your pipeline settings

  1. Give your pipeline a name. In my personal projects, I tend to use my repository name for this. The role name will be automatically filled out as you enter your pipeline name.
  2. Leave everything else as default and click next

Step 2: Add the source stage

  1. Select your source code provider. I usually store my code on Github.
  2. You will be prompted to connect your GitHub account to your AWS account
  3. Once you’ve connected the two, select your repository from the list and select your branch as master
  4. Ensure you select GitHub webhooks to automatically start your pipeline when a change occurs within your repository
Connect to your GitHub repository and select the appropriate branch

3. Add a build stage

  1. Select CodeBuild as your build provider. CodeBuild is Amazon’s continuous integration service that compiles code, runs tests, and produces software artifacts that are ready to deploy to production.
  2. Create your build project in CodeBuild. You will need to provide your project with the following:
  • Project name: choose a meaningful name for your code build project
  • Managed Image: use an image managed by AWS CodeBuild
  • Operating System: select Ubuntu as your preferred operating system
  • Runtime: select standard
  • Image: select aws/codebuild/standard:7.0
  • Image version: use the latest image available for your runtime version
  • Environment type: linux EC2
  • Use a buildspec file: this is key as it’ll allow us to store our build commands in a YAML formatted buildspec file.

A buildspec is a collection of build commands and related settings, in YAML format, that CodeBuild uses to run a build. Without a build spec, CodeBuild cannot successfully convert your build input into build output or locate the build output artifact in the build environment to upload to your output bucket. (Github link)

version: 0.2

phases:
install:
runtime-versions:
nodejs: latest
commands:
# Install project dependencies
- node -v
- npm i

build:
commands:
# Build the react app
- npm run build
- aws s3 sync build/ s3://my-app-reactbuild
- aws cloudfront create-invalidation --distribution-id E2R4D1DA76861U --paths /*

Once we have successfully created a build project, we will be redirected back to this page. Let’s now move on to next step

  • After the pipeline is created, it will automatically trigger when changes are pushed to the specified branch in your GitHub repository.
  • The pipeline will build your React app using CodeBuild, deploy it to the S3 bucket, and update the CloudFront distribution.
Congratulations! 🎉🎉🎉 You’ve successfully deploy your react application to S3 and Cloudfront using Code pipline✅

After the pipeline runs successfully, you should be able to access your deployed React app via the CloudFront distribution’s URL.

Conclusion

As you can see, integrating a CI/CD pipeline into your development environment is relatively simple. Setting up this kind of pipelines can automate your workflow hence enabling your developers to focus on, well — development. Hence, enabling you to deliver features faster to your users. Also, it will save you the hassle of trying to manually build and deploy your applications like I first did when I started working on my personal website.

If you’ve managed to get this far, pat yourself on the back — you’ve now set up a fully automated CI/CD pipeline within AWS.

Thanks for Visiting here…!!!

Github link:

You can also follow me on my LinkedIn profile by clicking on following link.

https://www.linkedin.com/in/pranitagughane/

--

--

Pranita Gughane
Pranita Gughane

Written by Pranita Gughane

"DevOps engineer by day, pipeline enthusiast by night. Ensuring your code deploys smoothly while I’m up at 2 AM wondering if I’ll ever get a full night’s sleep"

Responses (1)