Automated React App Deployment from CodeCommit to S3 using CodePipeline

Automated React Deployment from Codecommit to S3

Automated React App Deployment from CodeCommit to S3 using CodePipeline

Gone are the days when companies used to deliver production deployments every few months.

Now, in the time of agile, customers are looking for MVP(Minimum Viable Product) as early as possible.

And after the MVP, they need frequent deployment of additional features. May be every 15 days or some companies even deploy every few hours.

You might think, one deployment takes so much time, how to do so many deployments?

Don’t worry !!!

CICD Pipelines are there for your rescue. Once automated, all you need to do is commit your code in your source code repository and the rest is taken care of by the pipeline.

Don’t want to miss any posts from us? join us on our Facebook group, and follow us on Facebook, Twitter, LinkedIn, and Instagram. You can also subscribe to our newsletter below to not miss any updates from us.

How to Deploy React App to S3?

Before we automate the react app deployment from CodeCommit to S3, let’s first understand what it takes to deploy a react app to AWS S3.

Once you create your react app and test it locally, you can simply create a production-ready app by running the below command.

npm run build

After this command executes, it creates a build folder in the root directory. It basically bundles your React app and minifies it into simple HTML, CSS, and JavaScript files.

It provides an entry point, where your entire React app resides.

Hosting a React App on S3

Ideally, we have the optimized content of our react app in the build folder. So all we need is to copy the content of the build folder into an S3 bucket with website hosting enabled.

And you are done. 🙂

It’s that simple !!!

But wait a minute 🙂

Are you planning to copy the content of the build folder manually into the bucket?

I am sure, you are not !!!

In this post, we will see how to create a CICD pipeline using CloudFormation so that your pipeline is automated and you can sleep peacefully.

All I mean is, you only worry about making your React app better and the rest will be taken care of by the pipeline.

Did I convince you enough to go through this post 😛

Well, let’s go then !!!

Steps to Automate React App Deployment from CodeCommit to S3 using CodePipeline

  1. Create a React App and Test it Locally
  2. Create a BuildSpec file to be used by CodeBuild
  3. Zip your code to create a code commit repo
  4. Prepare CloudFormation Template for Pipeline
  5. Create the Pipeline Stack
  6. Make some changes to the code and push to code commit

Step 1: Create a React App and Test it Locally

Let’s start with creating a new React app. If you already have one, please feel free to head straight to step 2.

I am using AWS Cloud9 IDE for this and it comes with the latest npm version. Please feel free to use your favourite IDE.

Create a new react app

npx create-react-app my-app  

Navigate to created app directory-

cd my-app

Start NPM server-

 npm start

Test Locally

After the server is started, you can test your application on localhost. I am on cloud9 IDE and I will preview my running application from the menu bar.

deploy react app to s3

Step 2: Create a BuildSpec file to be used by CodeBuild

We will be using AWS CodeBuild to build our react app and then copy the content of the build folder into the S3 bucket.

CodeBuild needs a build spec specification or commands that it needs to execute when it starts building our code.

You can even add test code and add a test command so that CodeBuild your test your code as well.

Create a file buildspec.yml into the root directory of your application like below.

react app deployment with CICD

Add the below content in your buildspec.yml file.

version: 0.2
      nodejs: 12
      # Install dependencies needed
      - npm install

      # Upgrade AWS CLI to the latest version
      - pip install --upgrade awscli
      # Build the react app to give an optimized production build
      - npm run build
      # Copy the content of build folder into website s3 bucket
      - aws s3 sync build/ s3://$WEBSITE_S3_BUCKET/

Note: Please note that WEBSITE_S3_BUCKET in the command – aws s3 sync build/ s3://$WEBSITE_S3_BUCKET/ is an environment variable and is set during CodeBuild project creation.

Don’t worry about it now, you will see it in the CloudFormation template when we will prepare one for our pipeline.

Step 3: Zip your code to create a code commit repo

Once you are done testing your new app locally, we will create a CodePipeline using CloudFormation.

Our Pipeline will only have two stages.

  1. Source- CodeCommit
  2. Build -CodeBuild

While creating a code commit repo, we can either create an empty repo and upload the code there or create it with your sample code.

As we already have a sample code from above, so I would prefer to create the repo using it.

To do so, we need to create a zip containing all our code.

Note: Please make sure that extracting the zip file is directly giving you the project structure and no nested folder. Also, it should not contain any .git folder or .gitignore file

This is how it looks when I extract

react app folder structure

After you are ready with the zipped code, upload it to any S3 bucket you already have. We will need this bucket name and key while creating the CodeCommit repo.

Step 4: Prepare CloudFormation Template for Pipeline

As we want a fully automated CICD pipeline so we will use CloudFormation to create our pipeline and other important resources.

Our template contains the below resources.

  • An S3 Bucket to be used for website hosting
  • A read policy on the website bucket to allow the public to read
  • An artefact S3 Bucket to be used by CodePipeline
  • A policy for artefact bucket to allow read, write by CodeBuild etc.
  • A CloudWatch event rule to trigger our pipeline on code changes
  • A CodeCommit repo to store our code
  • A CodeBuild project
  • A Toolchain Role
  • A Pipeline

Here is the final template.

AWSTemplateFormatVersion: 2010-09-09
Description: Pipeline for the react web app

    Type: String
    Description: Project ID.
    Default: my-app
    Type: String
    Description: Bucket Name
    Default: preetitest-website
    Type: String
    Description: Bucket in which you have code
    Default: code-bucket
    Type: String
    Description: key of zipped code
    Default: test-react/


    Type: 'AWS::S3::Bucket'
      BucketName: !Ref WebsiteS3Bucket
        ErrorDocument: 'index.html'
        IndexDocument: 'index.html'
      AccessControl: PublicRead
        BlockPublicAcls: false
        BlockPublicPolicy: false
        IgnorePublicAcls: false
        RestrictPublicBuckets: false	  
    Type: 'AWS::S3::BucketPolicy'
      Bucket: !Ref TargetS3Bucket
          - Action: 
              - 's3:GetObject'
            Effect: Allow
              - !Sub 'arn:${AWS::Partition}:s3:::${WebsiteS3Bucket}/*'
            Principal: '*'
    Type: 'AWS::S3::Bucket'
      BucketName: cloudkatha-artifact-bucket
    Type: 'AWS::S3::BucketPolicy'
    Description: Setting Amazon S3 bucket policy for AWS CodePipeline access
      Bucket: !Ref ArtifactBucket
        Version: 2012-10-17
          - Action:
              - 's3:GetObject'
              - 's3:GetObjectVersion'
              - 's3:GetBucketVersioning'
              - !Sub 'arn:${AWS::Partition}:s3:::${ArtifactBucket}'
              - !Sub 'arn:${AWS::Partition}:s3:::${ArtifactBucket}/*'
            Effect: Allow
                - !GetAtt 
                  - ToolChainRole
                  - Arn
          - Action:
              - 's3:PutObject'
              - !Sub 'arn:${AWS::Partition}:s3:::${ArtifactBucket}'
              - !Sub 'arn:${AWS::Partition}:s3:::${ArtifactBucket}/*'
            Effect: Allow
                - !GetAtt 
                  - ToolChainRole
                  - Arn
    Type: 'AWS::CodeCommit::Repository'
    Description: Repo application source code
      RepositoryName: !Ref ProjectId
        BranchName: main
          Bucket: !Ref CodeBucket
          Key: !Ref CodeKey
      - ToolChainRole
    Type: 'AWS::CodeBuild::Project'
        Type: codepipeline
        Packaging: zip
      ServiceRole: !Ref ToolChainRole
          - Value: !Ref TargetS3Bucket
            Name: WEBSITE_S3_BUCKET
        Image: 'aws/codebuild/standard:3.0'
        ComputeType: medium
        Type: codepipeline
      Name: !Ref ProjectId

    Type: 'AWS::IAM::Role'
    Description: Creating role for codebuild
      Path: /
      RoleName: !Sub 'ToolChainRole-${ProjectId}'
        - PolicyName: ToolChainRolePolicy
              - Action:
                  - 'codecommit:*'
                  - 'codepipeline:*'
                  - 'codebuild:*'
                  - 's3:*'
                  - 'events:*'
                  - 'iam:PassRole'
                  - 'cloudwatch:*'
                  - 'kms:*'
                  - 'cloudformation:*'
                  - 'logs:*'
                Resource: '*'
                Effect: Allow

          - Action: 'sts:AssumeRole'
            Effect: Allow
    Type: 'AWS::Events::Rule'
          - CodeCommit Repository State Change
          - !Join [ '', [ 'arn:aws:codecommit:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref ProjectId ] ]
            - branch
            - referenceCreated
            - referenceUpdated
            - main
          - aws.codecommit
      Description: >-
        Rule for Amazon CloudWatch Events to detect changes to the source
        repository and trigger pipeline execution
      State: ENABLED
        - Id: ProjectPipelineTarget
          Arn: !Sub >-
          RoleArn: !GetAtt
            - ToolChainRole
            - Arn
      Name: Demo_Source_Event

      - ToolChainRole
      - ArtifactBucket
      - CodeBuildProject
    Type: 'AWS::CodePipeline::Pipeline'
    Description: Creating an AWS CodePipeline
      RoleArn: !GetAtt
        - ToolChainRole
        - Arn
      Name: !Sub '${ProjectId}-Pipeline'
        Type: S3
        Location: !Ref ArtifactBucket
        - Actions:
            - ActionTypeId:
                Owner: AWS
                Category: Source
                Version: 1
                Provider: CodeCommit
                PollForSourceChanges: false
                RepositoryName: !Ref ProjectId
                BranchName: main
              InputArtifacts: []
                - Name: !Sub '${ProjectId}-SourceArtifact'
              RunOrder: 1
              Name: ApplicationSource
          Name: Source
        - Actions:
            - ActionTypeId:
                Owner: AWS
                Category: Build
                Version: 1
                Provider: CodeBuild
                ProjectName: !Ref ProjectId
                - Name: !Sub '${ProjectId}-SourceArtifact'
              OutputArtifacts: []
              RunOrder: 1
              Name: PackageExport
          Name: Build
    Description: URL of S3 Website
    Value: !GetAtt TargetS3Bucket.WebsiteURL

Step 5: Create the Pipeline Stack

Grab the template from above and change the value of the below parameters.

  • ProjectId: An Id for your project(in lowercase only)
  • WebsiteS3Bucket: Bucket name for your React app
  • CodeBucket: Bucket in which you have stored zipped code
  • CodeKey: Key of the zipped code

Save the template as pipeline.yml and follow the below steps.

  • Login to AWS Management Console, navigate to CloudFormation and click on Create stack
  • Click on “Upload a template file”, upload pipeline.yml  and click Next
  • Enter the stack name and click on Next. In the configuration, keep everything as default and click on Next.
  • In the events tab of the stack, you can view the status.
  • Once the stack is successfully created, go to the Output tab
  • You can get the website URL from here and hit the endpoint
deploy a react aap to s3

On clicking the above URL we get the below screen- pretty basic what react create app provides as default

first webapp creation

Step 6: Make some changes to the code and push it to codecommit

Now that we were able to see the first deployment, let’s make some changes to the code and push it to the code commit.

I am using cloud9 and it comes with AWS-managed temporary credentials with my IAM user. So If my IAM user has CodeCommit access, I can clone the repo by doing the-

CodeCommit Repo -> Clone URL -> Clone HTTPS

Going to the terminal and issuing clone command like below.

 git clone

This clones the project for me into the IDE.

If you are using a local computer, you will need HTTPS credentials that you can generate from your IAM user(if only you have permission). You can follow this tutorial to set up your git locally with credentials.

Once the project is cloned, let’s edit the App.js

Then issue the below commands to push your changes.

git status
git commit -a -m "First try"
git push

After the code push, you can go to your pipeline and see that the pipeline is triggered.

Final pipeline status

Once your pipeline is successful, you can go to your website URL again and see that changes have been propagated.

Let’s go to the URL

Final REact app deployed to S3

For this tutorial URL was:

By the way, don’t try the above URL because after writing this post, I am gonna delete everything. So by the time you will read this. the above link will no longer work.


This post was all about react app deployment from CodeCommit to S3.

Finally, let’s summarize what we did in this post.

  • We created a react app from scratch and tested it locally
  • We learnt how to deploy a react app to S3
  • Created a CodeCommit repo with our sample code using CloudFormation
  • Created a Code pipeline using CloudFormation
  • Made changes to the code and pushed to CodeCommit
  • Verified the pipeline triggering on code push
  • Gathered the S3 website URL and checked the latest deployment

Enjoyed the content?

Subscribe to our newsletter below to get awesome AWS learning materials delivered straight to your inbox.

Don’t forget to motivate me by-

Suggested Read:

Leave a Reply

Your email address will not be published. Required fields are marked *