Skip to main content

Command Palette

Search for a command to run...

Deploy React App on S3 and CloudFront using CodePipeline

Published
5 min read

AWS CodePipeline is a fully managed continuous integration and continuous delivery (CI/CD) service provided by Amazon Web Services (AWS). It helps automate the building, testing, and deployment of applications.
Today, I'm going to write a blog post about deploying React websites on AWS S3 and CloudFront using CodePipeline.

STEP 1: Prerequisites:

1. AWS Account with access to S3, CodePipeline and Cloudfront.
2. React Application Code.
3. GitHub Repository

STEP 2: Setting Up GitHub Repository

Host your React app code in a GitHub repository.

STEP 3: Setting Up Amazon S3

Once the CodePipeline is configured, in the following steps, it will automatically deploy the code from your GitHub repository to this S3 bucket.

STEP 4: Configuring Amazon CloudFront

Amazon CloudFront is a content delivery service provided by Amazon Web Services (AWS). It's designed to help businesses and developers distribute content, including web pages, images, videos, and other resources, to users around the world with low latency and high data transfer speeds.

How to set up Cloudfront?

1. From the AWS Management Console, navigate to the CloudFront service. You can find it under "Networking & Content Delivery."

2. Create a Distribution: Click on "Create Distribution" to start the process

  1. Origin Settings: Configure the source of your content, which could be an S3 bucket created earlier.

4. Scroll down, and in the 'Origin Access Identity' section, select 'Create a new Identity.' After that, update the S3 bucket policy.

5. Under the 'Viewer Protocol Policy' setting, please choose 'Redirect HTTP to HTTPS.

6. I am keeping rest values as it is like domain name, SSL etc. Under the default root object, specify the file name as index.html, then proceed to create the distribution.

Our infrastructure setup is now ready. The next step is to build a CI/CD pipeline using CodePipeline.

STEP 5: Create a CodePipeline

Before setting up a CodePipeline, it's necessary to establish a connection with your GitHub repository. Follow these steps:

  1. Click on "Settings" in the AWS menu.

  2. In the left sidebar, select "Connections."

  3. Create a new connection.

  4. Provide the required information to link your GitHub account and repository to the connection.

On successful connection creation, it will show like this.

Now, we are good to go ahead with codepipeline creation.

1. Open AWS CodePipeline service and click on create pipeline.

2. Give desired name to pipeline and click on next.

3. Under source choose a GitHub version 2 option. In connection name, select earlier created github connection, repository name and branch name choose.

4. Build Stage:

Under Build provider choose AWS CodeBuild. Under Project name, create a new project and it will open a new window with few options.

5. First option is to set desired project name.

6. Under the Environment, choose the managed image, Amazon-Linux as operating system, runtime-standard and latest image version.

7. Under buildspec file, need to add commands to build react code. Copt the below buildspec file content and paste it in Insert build commands.

version: 0.2
phases:
  install:
    runtime-versions:
      nodejs: 18
    commands:
      - echo installing yarn...
      - npm install -g yarn
      - echo yarn -v
  pre_build:
    commands:
      - echo Installing source NPM dependencies...
      - yarn install    
      - npm install webpack@latest webpack-cli@latest --save-dev
      - pip install awscli --upgrade --user
  build:
    commands:
      - echo Build started on `date`          
      - npm install --legacy-peer-deps
      - yarn build 
      - ls -l build
artifacts:
  files:
    - '**/*'
  base-directory: 'build'

It will be show like this:

8. All things are done under create a project. Now this will take us back to Build step window. Project name will be filled up and click on next.

9. Deploy Stage
After completing the build step, let's move on to preparing the deployment stage. The first option is to select 'Amazon S3' as the Deploy provider. Choose the bucket name and also ensure to check the option 'Extract file before deploy.'

10. After reviewing all CodePipeline configurations on the next page, proceed by clicking on 'Create a Pipeline.

After successfully creating the pipeline, it will automatically start, deploying the 'react-welcome-code' to the specified S3 bucket and Cloudfront distribution.

The pipeline has been successfully deployed. Now, let's browse the code.

Final Step: Invalidate Cloudfront Cache

To apply changes immediately on the website, it's essential to invalidate the cache. This process ensures that any outdated or cached content is replaced with the latest updates. To accomplish this task, we will write a Lambda code and include an 'Invalidate Cache' step in the CodePipeline.

Lambda code:

import boto3
import time
def lambda_handler(event, context):
     allFiles = ['/*']
     client = boto3.client('cloudfront')
     invalidation = client.create_invalidation(
        DistributionId='ENYIF5OAP33CY',
        InvalidationBatch={
            'Paths': {
                'Quantity': 1,
                'Items': allFiles
        },
        'CallerReference': str(time.time())
     })

     pipeline = boto3.client('codepipeline')
     response = pipeline.put_job_success_result(
         jobId=event['CodePipeline.job']['id']
     )
     return response

Here DistributionId= 'ENYIF5OAP33CY' replace it with your Cloudfront distribution id.

Second Steps:
Edit the existing 'react-welcome-code' pipeline and add a new stage after the deploy stage step.

You can assign any desired name to this stage and use Lambda as an Action provider. Choose the function name created earlier and specify the input artifact name.

Once all is done it will invalidate the Cloudfront cache on each new deployment.

That's it. In this article, we have successfully deployed the react app on S3 and Cloudfront with an invalid cache using CI/CD Codeipeline.