Deploy a React App to Amazon S3 + CloudFront using CDK in 3 Lines of Code!

Deploy a React App to Amazon S3 + CloudFront using CDK in 3 Lines of Code!

ยท

4 min read

Project Overview ๐Ÿ“–

You've built an amazing React app that you want to deploy for the world to see!

This guide will teach you how to deploy a React based web application using Amazon S3 for hosting and Amazon CloudFront as a CDN. Best of all, we will deploy the project with AWS CDK in only 3 lines of code!

You heard that right, 3 lines of code!! ๐Ÿ˜Ž๐Ÿ˜ค

Architecture Overview ๐Ÿ—

image.png

Setup React App

First we will setup a react application, for simplicity I'm going to use create-react-app. You can of course use your existing react application if you'd like!

Create a fresh empty project folder and run the following command to generate a react app. This will create a boiler plate react application in a sub-folder called frontend.

npx create-react-app frontend

Let's edit App.js a little

import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Hello from AWS!!
        </p>
      </header>
    </div>
  );
}

export default App;

Running npm run start we should see our app running locally on our machine.

And we do, Nice!

image.png

Setup a New CDK Application

Now that we have a react app setup let's shift our attention to CDK.

From the root of your project folder run the following to generate a CDK application and install the CDK-SPA-Deploy library we will be using.

mkdir cdk && cd cdk
cdk init app --language typescript
npm install cdk-spa-deploy

At this point you should have a project structure like this

.
โ”œโ”€โ”€ cdk
โ”‚   โ”œโ”€โ”€ README.md
โ”‚   โ”œโ”€โ”€ bin
โ”‚   โ”‚   โ””โ”€โ”€ cdk.ts
โ”‚   โ”œโ”€โ”€ cdk.json
โ”‚   โ”œโ”€โ”€ jest.config.js
โ”‚   โ”œโ”€โ”€ lib
โ”‚   โ”‚   โ””โ”€โ”€ cdk-stack.ts
โ”‚   โ”œโ”€โ”€ package-lock.json
โ”‚   โ”œโ”€โ”€ package.json
โ”‚   โ”œโ”€โ”€ test
โ”‚   โ”‚   โ””โ”€โ”€ cdk.test.ts
โ”‚   โ””โ”€โ”€ tsconfig.json
โ””โ”€โ”€ frontend
    โ”œโ”€โ”€ README.md
    โ”œโ”€โ”€ package-lock.json
    โ”œโ”€โ”€ package.json
    โ”œโ”€โ”€ public
    โ”‚   โ”œโ”€โ”€ favicon.ico
    โ”‚   โ”œโ”€โ”€ index.html
    โ”‚   โ”œโ”€โ”€ logo192.png
    โ”‚   โ”œโ”€โ”€ logo512.png
    โ”‚   โ”œโ”€โ”€ manifest.json
    โ”‚   โ””โ”€โ”€ robots.txt
    โ””โ”€โ”€ src
        โ”œโ”€โ”€ App.css
        โ”œโ”€โ”€ App.js
        โ”œโ”€โ”€ App.test.js
        โ”œโ”€โ”€ index.css
        โ”œโ”€โ”€ index.js
        โ”œโ”€โ”€ logo.svg
        โ”œโ”€โ”€ reportWebVitals.js
        โ””โ”€โ”€ setupTests.js

Open up lib/react-aws-cdk-stack.ts. Note that this class extends cdk.Stack. Stacks are the basic unit of development in CDK, all your AWS resources are defined within the scope of a stack. Let's make use of the SPADeploy construct we installed.

import * as cdk from '@aws-cdk/core';
import { SPADeploy } from 'cdk-spa-deploy';

export class CdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new SPADeploy(this, 'my-react-app').createSiteWithCloudfront({
      indexDoc: 'index.html',
      websiteFolder: '../frontend/build'
    })
  }
}

Let's talk about what the above code is doing. We are using the SPADeploy construct we installed earlier and are calling createSiteWithCloudfront. As the name suggests this method will create a site that uses CloudFront as a CDN. If you don't want to use CloudFront you can use the createBasicSite method instead. Read more about the SPADeploy construct on Github

Since I'm using create-react-app, my index file is by default index.html. The website property takes in the path to your production react build, in the case of create-react-app that folder is called build. Use the values that suite your setup ๐Ÿ’ฏ

Upon deploying, this construct will handle uploading our build to S3 and will setup an S3 bucket to host our website and a CloudFront distribution to serve as a CDN.

Let's write some npm scripts to automate our build and deployment. Add these npm scripts to your cdk/package.json

"scripts": {
    "build-cdk": "cdk synth",
    "build-frontend": "cd ../frontend && npm run build",
    "deploy": "npm run build-cdk && npm run build-frontend && cdk deploy CdkStack"
  }

To deploy run

npm run deploy

This command will build your react app and deploy the CloudFormation stack, you will be asked to confirm the IAM changes. After it's finished deploying, the stack will output the public URL where you can access your site!!

image.png

Paste this URL into your browser to access your live site ๐Ÿ˜Ž

image.png

That's it! you've deployed your react app to AWS using S3 and CDK in a couple lines of code! How powerful is that? ๐Ÿ˜ค

Follow me on twitter for more AWS content ๐Ÿ™Œ๐Ÿป

ย