DEV Community

Kanani Nirav
Kanani Nirav

Posted on

2 1

Deploy a React App to Amazon S3 using Github Actions And Bitbucket Pipelines

This walk-through is a simple step-by-step guide to deploying a React Web application to Amazon S3 using Github Actions or Bitbucket Pipelines

Image description

Amazon Simple Storage Service (S3)?

Amazon Simple Storage Service (S3) is one of the numerous services offered by Amazon Web Services(AWS), an on-demand cloud computing platform. Amazon S3 provides scalable object storage through a web service interface that is used to store and retrieve any amount of data, at any time, from anywhere on the web.

Github Actions?

GitHub Actions makes it easy to automate your workflows like build, test, and deploy when using Github, a platform that provides hosting for software development version control using Git.

In this post, we will go through:

  1. How to create an Amazon S3 bucket.

  2. How to set up an S3 bucket for Web Hosting.

  3. How to configure our Github actions to automatically deploy changes to the S3 bucket. In the end, deploy a React App to live.

Before we get started, you need to have:

  1. Github Account

  2. Bitbucket Account

  3. AWS Account

Create Amazon S3 Bucket

First, log in to your AWS account. On the AWS Management Console, click S3 from the list of services under the Storage section or use the search bar.

On the Amazon S3 page, click on Create Bucket

To create a bucket, provide a Bucket Name. An S3 bucket name must be unique amid all buckets universally in Amazon S3. Also, take note of the Region you are creating the bucket in. For this post, we are using Asai Pacific(Tokyo) which is ap-northeast-1

Image description

Uncheck the checkbox for Block all public access. After, click on Create bucket.

Image description

Add Bucket Policy

This makes the contents of your bucket publicly available. This action is not recommended when working with S3 buckets, but for this our purpose this is fine.

Under Buckets, choose the name of your bucket (react-deploy-ci-cd) > Choose Permissions > Choose Bucket Policy.

Copy the following bucket policy, and paste it in the editor.

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

Update the snippet to include your bucket name. In the bucket policy, <bucket-name> you must update this name to match your bucket name.
Then, click on Save changes

Enable Static Website Hosting

Choose Properties > Choose Static website hosting.Click on edit and enable static website hosting.

Image description

In Static website hosting choose enable and type index.html in the Index document field and Save changes.

Image description

Note: Take note of the Endpoint URL, our website will be accessible in the browser using this URL.

Create and Push React App to GitHub And Bitbucket

Now we have our S3 bucket, it’s time to create and push our React App to GitHub.

  • Create a New Repository on GitHub.

  • Create a New Repository on Bitbucket.

After creating a repository, You could:

  • Create a React application using Create React App and ensure that there is a build script in the package.json file will output to a dist folder. OR Clone the sample React App repository S3-Github Actions React App that we will be using for this post and add your repository's remote URL. GitHub Repo - S3-Github Actions React App
1. For Create repository
$ git init # initialize git locally
$ git add . # add changes to git
$ git commit -m "React App" # commit changes
$ git remote add origin <your-github-repo-url.git> # add remote origin
$ git push -u origin master # push to remote master branch
2. For Clone sample React App repository
$ git remote add actions <your-github-repo-url.git> # add remote actions
$ git push -u actions master # push to remote master branch
view raw git-commands hosted with ❤ by GitHub

To set up our workflow, we need to provide the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and AWS_REGION of the S3 bucket in other to connect successfully to Amazon S3.

Get AWS Authorization

On the AWS Console:

  1. Click on IAM

  2. Click on Users and select your preferred user.

  3. Under Security Credentials, click on Create Access Key. This will create an AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, copy these values. You can also manage key access by either deleting or making it inactive.

Never share your access keys.

So that’s why we will be passing some very important values as Secrets on GitHub then later access them in the workflow file using the expression syntax. ${{ <expression> }}

Back to Github

Click on the Settings tab, Select Secret on the left menu, then click on New Secret to add a secret providing the Name and Value.

Name Value
AWS_ACCESS_KEY_ID your-aws-access-key-id
AWS_SECRET_ACCESS_KEY your-aws-secret-access-key
AWS_REGION your-aws-s3-region
S3_BUCKET your-aws-s3-bucket-name
view raw aws-config.csv hosted with ❤ by GitHub

Image description

Setup Github Actions

Now, we have the S3 bucket set up and a React app to deploy.

On the GitHub repository, click on the Actions tab to open the Github actions page. On the Actions page, click on the set up a workflow yourself -> button, this will redirect to a new page with a web editor containing some code.

Image description

First, let’s name the workflow file. You can leave the filename as main.yml, but it is best to give it a descriptive name.
Copy and paste the code snippet into the editor. Copy and Paste, a developer’s superpower.

# This is a basic workflow to help you get started with Actions
name: s3-depl
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Build React App
run: npm install && npm run build
- name: Deploy app build to S3 bucket
run: aws s3 sync ./build/ s3://<bucket-name> --delete
view raw main.yml hosted with ❤ by GitHub

Now, let’s breakdown the code snippet above.
  • name: We define the name of this action. This will be used to identify the action amid may others you may have.

  • on: We define trigger with on : push also the branch. This workflow will run anytime you push code to the master branch.

  • jobs: Workflow run is made up of one or more jobs and they run in parallel by default.

  • steps: A job contains a sequence of tasks called steps. Steps can run commands, run setup tasks, or run action in your repository and each step starts either with a uses: or a name:.

  • actions/checkout@v3: This action checks-out your repository, so your workflow can access it.

  • aws-actions/configure-aws-credentials@v1: This configures AWS credentials and region environment variables for use in other GitHub Actions.

  • Build React App: This step block installs the node packages and runs the build in the package.json file, which creates a build folder in the root directory.

  • Deploy app build to S3 bucket: This deploys the newly created build to S3 bucket <bucket-name> (replace <bucket-name> with the name of your S3 bucket. Mine is react-deploy-ci-cd).

To save, click on the Start Commit then Commit New File. This will,

  • save the action, creating a .github directory with a workflows directory in it that contains the new file main(the file name you used earlier)

  • Trigger the action.

To check the progress, click on the Actions tab.

Image description

Setup Bitbucket Pipelines

Setup the Deployment variables for you repository.

On the Bitbucket repository, open Repository settings page and click on Deployments and create Variables according to your environments here we are creating for production.

Image description

After that, For bitbucket pipelines add new file with name bitbucket-pipelines.yml and Copy and paste the code snippet into file.

# Template React Deploy
# This template allows you to deploy your React app to an AWS S3 bucket and invalidate the old AWS Cloudfront distribution.
# The workflow allows running tests, code linting and security scans on feature branches (as well as master).
# The react app will be validated, deployed to S3 and trigger an AWS Cloudfront distribution invalidation to refresh the CDN caches after the code is merged to master.
# Prerequisites: $AWS_ACCESS_KEY_ID, $AWS_SECRET_ACCESS_KEY, $S3_BUCKET setup in the Deployment variables.
image: node:16
# Workflow Configuration
pipelines:
default:
- parallel:
- step:
name: Build and Test
caches:
- node
script:
- npm install
# CI=true in default variables for Bitbucket Pipelines https://support.atlassian.com/bitbucket-cloud/docs/variables-in-pipelines/
- npm test
- step:
name: Lint the node package
script:
# Run your linter of choice here
- npm install eslint
- npx eslint src
caches:
- node
branches:
master:
- parallel:
- step:
name: Build and Test
caches:
- node
script:
- npm install
# CI=true in default variables for Bitbucket Pipelines https://support.atlassian.com/bitbucket-cloud/docs/variables-in-pipelines/
- npm test
- npm run build
artifacts:
- build/**
- step:
name: Security Scan
script:
# Run a security scan for sensitive data.
# See more security tools at https://bitbucket.org/product/features/pipelines/integrations?&category=security
- pipe: atlassian/git-secrets-scan:0.5.1
- step:
name: Deploy to Production
deployment: Production
# trigger: manual
clone:
enabled: false
script:
# sync your files to S3
- pipe: atlassian/aws-s3-deploy:1.1.0
variables:
AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
S3_BUCKET: $S3_BUCKET
ACL: "public-read"
LOCAL_PATH: 'build'
# # triggering a distribution invalidation to refresh the CDN caches
# - pipe: atlassian/aws-cloudfront-invalidate:0.6.0
# variables:
# AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
# AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
# AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
# DISTRIBUTION_ID: '123xyz'

If you are using aws-cloudfront then uncomment last pipe in yml file and remove ACL: public-read. it will triggering a distribution invalidation to refresh the CDN caches.

Finally both action ran successfully. Yay!! 🎊

You can now check your S3 bucket, you would see that the build files have been uploaded to it.

Image description

Our site is now live!!! On the browser, go to the Endpoint URL (http://<s3-bucket>.s3-website-<s3-region>.amazonaws.com) that we came across when enabling Static Website Hosting. Now, any change you make to your react app will build and upload to your S3 bucket which will update live.

Image description

You can go on to work with Github or Bitbucket Actions by triggering an action on Pull Request that might run some CI tests and perform several steps before deploying to your S3.

If this guide has been helpful to you and your team please share it with others!

Retry later

Top comments (0)

Retry later
Retry later