(CI/CD)Deploy React app to AWS s3 using Github actions
I recently wanted to setup a CI/CD pipeline to automatically deploy my react app to my s3 bucket. This article assumes you know git, react basics
and have an AWS account
with appropriate rights. So let’s get started.
AWS s3 setup
Let us first setup our s3 bucket in AWS.
- Log in to your AWS console and select
s3
from services. - Create a new bucket with the following settings,
- Provide
name
andregion
. - Unselect
Block all public access.
(in case you want your website to be publicly accessible) - Select
I acknowledge current settings
as shown below.
- You can leave other settings as it is for now and scroll all the way down to click
create bucket
button.
3. Now that your bucket is created, let us modify the bucket policy like below (under Permissions tab),
- You’re basically allowing(effect) the public(principal) to view(action) your whole app(resource).
{
"Version": "2021-05-27",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<your-bucket-name>/*"
}
]
}
4. Now, enable static website hosting (under Properties tab)
- Select
use this bucket to host a website
option. - You can fill
index.html
for index and error document. (important)
5. Now that you’ve setup your s3 bucket, you can manually upload your build
folder or a hello word
html file and try opening it to check if your website works fine.
Github actions setup
Having setup our s3 bucket, lets get started with setting up our Github.
- Once you upload your code to Github, under
Actions
tab, clicksetup workflow yourself.
2. It will create a .yml
file for you like below,
- Let’s first click
start commit
and make it a part of our repo.
3. Now, let’s pull master
and start editing the main.yml
file
<your_repo> ----> .github ----> workflows ----> main.yml
4. The .yml
file has three parts as below,
- To put it in simple words, we are saying “Please run certain commands for me whenever my master branch changes”
# This is a basic workflow to help you get started with Actionsname: CI# Controls when the action will run.on:# A workflow run is made up of one or more jobs that can run sequentially or in paralleljobs:
- You can leave the
name
as CI(as above).
* On Part
- Let us add our main branch name like below.
Translating below snippet to english, we are specifying our branch name and on what actions(pull, push) it must build and deploy for us.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
pull_request:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
* Jobs part
- Here you can specify all the steps you want to perform before deploying to s3, like (build, test etc). Here we will just see about
build
.
To put it in simple words, we are saying, hey “Build my app on
ubuntu-latest
with node-version12.18.3
“
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.18.3]
- After strategy, we are going to add instructions as below snippet.
Crux of the below snippet is that, we are writing steps to checkout out master branch and do an
npm i
and then build our app usingnpm build
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Use the node version specified in the strategy
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Git checkout
uses: actions/checkout@v2
# Install packages
- name: Install packages
run: |
npm install
# Build an optimized production build
- name: Production build
run: |
unset CI
npm run build
# Deploy to the S3 server
- Last step is to give instructions to deploy to s3.
Thanks to jakejarvis’s action, we can easily deploy to our s3 bucket. Translating the below snippet to english,
We are asking Jake’s action to deploy
build
folder to ours3 bucket
.
# Deploy to the S3 server
- name: Deploy to S3
uses: jakejarvis/s3-sync-action@master
with:
args: --acl public-read --delete
env:
AWS_S3_BUCKET: ${{ secrets.AWS_PRODUCTION_BUCKET_NAME }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
AWS_REGION: ${{ secrets.AWS_REGION }}
SOURCE_DIR: "build"
After adding all the above, your .yml
file should look like this,
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
pull_request:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# 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
strategy:
matrix:
node-version: [12.18.3]
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Use the node version specified in the strategy
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Git checkout
uses: actions/checkout@v2
# Install packages
- name: Install packages
run: |
npm install
# Build an optimized production build
- name: Production build
run: |
unset CI
npm run build
# Deploy to the S3 server
- name: Deploy to S3
uses: jakejarvis/s3-sync-action@master
with:
args: --acl public-read --delete
env:
AWS_S3_BUCKET: ${{ secrets.AWS_PRODUCTION_BUCKET_NAME }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
AWS_REGION: ${{ secrets.AWS_REGION }}
SOURCE_DIR: "build"
5. One last step pending is to add our AWS_PRODUCTION_BUCKET_NAME, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION
to our Github secrets (under settings
tab).
AWS_PRODUCTION_BUCKET_NAME
: name of your bucket.AWS_REGION
: your bucket’s region
- For
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
,
Please go toMy security credentials
- Click
create access key
, copyaccess key id
andsecret access key id
, copy them to Github secrets.
6. You are finally done with the setup. Go ahead, push some changes to master, you’ll see build happening.
7. Once it is success, you can visit your app hosted on s3 to verify the changes.
That’s it :) You’re CICD is ready.
Note: You can add staging or dev env too. Just create appropriate file under workflows, select the branch for staging and config your bucket names and you should be good.
Thank you for reading !