DEV Community

Dhiraj Bhatt
Dhiraj Bhatt

Posted on

How to deploy a static web app on AWS S3 for free?

So you built a static react web app, and you want the world to see it. This post provides a step-by-step guide on deploying your static web app on Amazon S3 for free.

For this tutorial, you will need

  • a basic understanding of react web apps, terraform and AWS S3
  • an activated AWS account. If you don't have one yet, you can follow instructions here to set it up
  • an AWS IAM user with
    • AWS API keys (Access Key ID and Secret Access Key) set up. You can follow instructions here to setup and configure the IAM user.
    • Permissions to create/delete S3 buckets, add IAM policies
  • Terraform CLI to set up our infrastructure on AWS
  • AWS CLI which has been configured with the IAM user API keys

AWS has a free tier so running the steps below should not cost you anything. In any case, make sure you TERMINATE all your resources after completing this tutorial to avoid any unwanted charges in your AWS account.

Preparing the package

I presume you already have a static react web app which you want to deploy. If not, you can pull a sample web application from my repository. I will be writing this guide using the indecision-app below. It has been build using yarn and webpack, though the steps should be easily reproducible with other package managers (npm, gulp, etc.)

$ git clone https://github.com/Dhiraj072/indecision-app.git

Once you have the app, build a production package.

$ yarn webpack -p

This above command will create a public/ directory inside your project folder, containing everything required to host your web application, including an index.html, bundle.js, etc.

Setting up AWS infrastructure

We will write the terraform configuration file main.tf step-by-step in this section. This file tells terraform which AWS resources to instantiate, and their respective configuration. Full version of the file can be found here.

  • Create a blank main.tf file in your project dir

  • Add below to our main.tf to tell terraform we are using AWS for our infrastructure

provider "aws" {
  # region you want your resource to be in
  region = "ap-southeast-1" 
}
  • We store our terraform states locally for now, so add
terraform {
  backend = "local"
}
  • To define local variables we will be using later on, add
locals {
  s3_origin_id = "myappS3Origin"
  app_name = "my_app"
}
  • Finally, add the config to create the S3 bucket we want our app to be hosted in. This also sets the IAM policy to allow public read as we want everyone to be able to access our web app.
resource "aws_s3_bucket" "my_app" {
  bucket = "${local.app_name}" # S3 bucket name
  acl    = "public-read"
  website {
    index_document = "index.html" # our web app's entry point
  }
  policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowPublicReadAccess",
      "Effect": "Allow",
      "Principal": "*",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": [
        "arn:aws:s3:::${local.app_name}/*"
      ]
    }
  ]
}
POLICY
}
  • Save your main.tf file

  • Set the environment variable for terraform to be able to access AWS

$ export AWS_SECRET_ACCESS_KEY=<YOUR_AWS_SECRET_ACCESS_KEY>
$ export AWS_ACCESS_KEY_ID=<YOUR_AWS_ACCESS_KEY_ID>
  • Initialize terraform
$ terraform init
  • Spin up the AWS infra, type y when asked for confirmation
$ terraform apply

Terraform may take 5-10 minutes to spin everything up. Once complete, you can login to you AWS account and you should see you AWS bucket created.

Your AWS infrastructure is now ready to host your web application.

Deploying the package

Finally, you can deploy the package we built earlier to S3 by running the following AWS CLI command in the project dir

$ aws s3 sync public/ s3://my_app

Accessing deployed web app

You should be able to access the application at https://s3-ap-southeast-1.amazonaws.com/my_app/index.html. This is basically the Object URL of the index.html file inside our S3 bucket my_app.

Terminating created resources

AWS has a free tier so running the steps in this tutorial should not cost you anything. In any case, do TERMINATE all your resources to avoid any unwanted charges by running the following command in your project dir

$ terraform destroy

Top comments (2)

Collapse
 
aodev profile image
AoDev

I remember I was doing that a few years ago. Until I found Netlify and moved everything there. I am not advertising for them, it's just that I remember how many posts like yours I've read to be able to host static sites on S3 and it was quite difficult at that time. But my actual goal was to quickly deploy SPA's or landing pages for free, and if this is your goal too, you might wanna check their services. ;)

Collapse
 
dhiraj072 profile image
Dhiraj Bhatt • Edited

Netlify looks promising. And I agree, AWS S3 is not the most easy way to deploy a static app. Though when I did this, it was to get myself familiar with AWS technologies and Terraform. And wrote the same into a post :) Maybe it’s worth writing a post on comparison of various ways one can deploy an app!