Deploy a React App to AWS S3 with GitHub Actions: A Step-By-Step Guide
Tags: javascript, react, aws, programming
Published: 2022-08-16 14:28:48

---
title: Deploy a React App to AWS S3 with GitHub Actions: A Step-By-Step Guide
published: true
date: 2022-08-08 16:02:16 UTC
tags: javascript,react,aws,programming
canonical_url: https://javascript.plainenglish.io/deploy-a-react-app-to-aws-s3-with-github-actions-a-step-by-step-guide-3572265332a3
---

#### In this beginner-friendly article, you can find out how to deploy your React App to AWS S3 using GitHub Actions.

![](https://cdn-images-1.medium.com/max/1024/0*AuN2sfBI0OqSp4mA)
_Photo by Lautaro Andreani on Unsplash_

After reading different articles, it was a little bit difficult to get all the pieces of the puzzle together so I have decided to create a step-by-step guide for beginners so you can deploy your app in less than 10 minutes.

This is what is covered in case you want to jump to a particular section:

1. Create React App
2. AWS: Create IAM user
3. AWS: Create S3 Bucket
4. GitHub Actions

### 1. Create React App

From your favourite terminal, run:

```
yarn create react-app test-aws-github-actions --template typescript
```

For more information about the script, you can [visit the documentation of create react app](https://create-react-app.dev/docs/adding-typescript/). If you run the project with yarn start you should be able to see the classic template.

![](https://cdn-images-1.medium.com/max/1024/1*Rv8sPMXOQjoCSevCu2Gd1w.png)
_Create React App Template_

I also want to cover how to use environment variables so I’m going to add a .env file and update the main text. The environment variable is:

```
REACT_APP_MAIN_TEXT="Testing AWS"
```

It’s a very simple text but it will help us understand the process. You can see the change in the git history in the image. It’s just displaying the text on the main screen.

![](https://cdn-images-1.medium.com/max/1024/1*OJ6filz6St_aivVw9WzxjQ.png)

As you can see, the text from the environment variable is displayed on the main page below the React icon.

![](https://cdn-images-1.medium.com/max/1024/1*x3Z4uAAiqsVGQljtiSNkJQ.png)
_React with environment variable_

Now you can push the code to a Github repository and let’s start looking at the AWS side of things.

### 2. AWS: Create IAM user

The first thing that you need is a user in AWS. From the IAM console, add a user. There are 5 steps in the process of creation

#### Create User Step 1

Name the user as you want. I’m creating a user only for this project so I have named it the same way. In GitHub actions, we need a key so you can select it in the initial screen.

![](https://cdn-images-1.medium.com/max/1024/1*ohTs0DyKe16ck2ytAXHW8w.png)
_IAM create user 1_

#### Create User Step 2

The second step is to provide permissions to the user. You can select AdminsitratorAccess

![](https://cdn-images-1.medium.com/max/1024/1*VTtEmal0MoQx6qnAFMJK0w.png)
_IAM create user 2_

#### Create User Step 3

This step allows you to add tags. Feel free to add any relevant things that can be useful for your admin.

![](https://cdn-images-1.medium.com/max/1024/1*sMXlgMJ6uBn5SX9MEtb4-w.png)
_IAM create user 3_

#### Create User Step 4

Now you can review the information provided in the previous steps. This will create the user for you so check the details to ensure it’s all correct.

![](https://cdn-images-1.medium.com/max/1024/1*3kyNp6IG926-a4Q0WLykYg.png)
_IAM create user 4_

#### Create User Step 5

This is the summary of the user. You’ll see an access key and a secret that you need to save as it will be used by the GitHub actions.

![](https://cdn-images-1.medium.com/max/1024/1*bXP2r8IAkR-d6fEZjEITSw.png)
_IAM create user 5_

### 3. AWS: Create S3 Bucket

In AWS, create an S3 bucket: [https://s3.console.aws.amazon.com/s3/bucket/create](https://s3.console.aws.amazon.com/s3/bucket/create)

Here, it’s important to enable the ACLs; otherwise, you’ll get an error from GitHub actions.

![](https://cdn-images-1.medium.com/max/1024/1*xeDlgIlYk1V5z9vH1qPaTg.png)
_Create AWS S3_

And unblock the public access.

![](https://cdn-images-1.medium.com/max/1024/1*PTbuZhGjFWJCDpqr1ThTcQ.png)
_Create AWS S3_

In the properties area, you can find a section for static website hosting. Enable the static website hosting and update the Index document and Error document to index.html.

![](https://cdn-images-1.medium.com/max/1024/1*DqfucOfjdcQG5inbhn59_w.png)

After you save the changes, you will see the URL for the hosting.

![](https://cdn-images-1.medium.com/max/1024/1*3pmrjUaZ0ZQd4ga8c3PGEw.png)
_Static Website Hosting AWS S3_

That is all with AWS.

### 4. GitHub actions

In the repo, create a new file.

```
name: Deploy AWS
on:
  push:
    branches:
      - main

env:
  REACT_APP_MAIN_TEXT: "Successfully deployed in AWS"
  AWS_S3_BUCKET: ${{ secrets.AWS_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"

jobs:
  build:
    runs-on: ubuntu-latest

strategy:
      matrix:
        node-version: [16.x]

steps:
    - uses: actions/checkout@v1
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}

- name: Yarn Install
      run: yarn install

- name: Staging Build
      run: yarn build

- name: Deploy to S3
      uses: jakejarvis/s3-sync-action@master
      with:
        args: --acl public-read --follow-symlinks --delete
```

In GitHub, update the [action secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) including:

- AWS\_BUCKET\_NAME
- AWS\_ACCESS\_KEY\_ID
- AWS\_SECRET\_ACCESS\_KEY
- AWS\_REGION

![](https://cdn-images-1.medium.com/max/1024/1*ynRDWdOqDxoPuxivLDsPRA.png)
_GitHub secrets_

Once you commit and push, you’ll see the action running:

![](https://cdn-images-1.medium.com/max/1024/1*Z_MJGMdfVZoAcbZRkz3w_g.png)
_GitHub Action_

If you check your S3 bucket, you’ll see all the files from the build folder:

![](https://cdn-images-1.medium.com/max/1024/1*Ob2THT2eSdle53eVcPPmig.png)
_AWS S3 Files deployed from GitHub Actions_

And you’ll be able to see your React app working:

![](https://cdn-images-1.medium.com/max/1024/1*oUg2m-sRJGgoo1elBfXzSw.png)
_React App Deployed in AWS_

### Troubleshooting

#### Issues with paths

If you haven’t set up the hosting, you will see an issue with some paths. This is because the bucket will manage the URLs and with React, as it’s a single-page app, it needs all the routes pointing at the index.html so React can manage the routing by itself.

```
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
</Error>
```

![](https://cdn-images-1.medium.com/max/1024/1*sWdu8ItKqfalp1bZsDj_tw.png)

To fix it, you need to make a small update in the S3 configuration in the area of Website Hosting. See the step.

#### Issues with ACL

If you are getting an error related to ACL in your GitHub actions, it is because ACLs are disabled. You need to enable them in the AWS S3 config.

```
upload failed: build/asset-manifest.json to s3://***/asset-manifest.json An error occurred (AccessControlListNotSupported) when calling the PutObject operation: The bucket does not allow ACLs
upload failed: build/robots.txt to s3://***/robots.txt An error occurred (AccessControlListNotSupported) when calling the PutObject operation: The bucket does not allow ACLs
upload failed: build/logo512.png to s3://***/logo512.png An error occurred (AccessControlListNotSupported) when calling the PutObject operation: The bucket does not allow ACLs
upload failed: build/static/js/787.e67aebaf.chunk.js.map to s3://***/static/js/787.e67aebaf.chunk.js.map An error occurred (AccessControlListNotSupported) when calling the PutObject operation: The bucket does not allow ACLs
upload failed: build/static/css/main.e6c13ad2.css to s3://***/static/css/main.e6c13ad2.css An error occurred (AccessControlListNotSupported) when calling the PutObject operation: The bucket does not allow ACLs
```

![](https://cdn-images-1.medium.com/max/1024/1*i461ReBNfVJcmnfpzlLY6w.png)

To fix it, you need to make a small update on the AWS S3 config enabling ACLs.

That’s it, thank you.

* * *