Create an S3 Bucket

To be able to host our note taking app, we need to upload the assets that are going to be served out statically on S3. S3 has a concept of buckets (or folders) to separate different types of files.

A bucket can also be configured to host the assets in it as a static website and is automatically assigned a publicly accessible URL. So let's get started.

Create the Bucket

First, log in to your AWS Console and select S3 from the list of services.

Select S3 Service screenshot

Select Create Bucket and pick a name for your application and select the US East (N. Virginia) Region Region. Since our application is being served out using a CDN, the region should not matter to us.

Create S3 static website Bucket screenshot

Click Next through the configure options step.

Create S3 static website Bucket next configure options screenshot

In the permissions step, make sure to uncheck Block new public bucket policies and Block public and cross-account access if bucket has public policies. Making buckets public is a common security error, but in our case we'll be serving our app from the bucket, so want it to be public.

Create S3 static website Bucket next permissions screenshot

Click Create bucket on the review page to create the bucket.

Create S3 static website Bucket next review screenshot

Now click on your newly created bucket from the list and navigate to its permissions panel by clicking Permissions.

Select AWS S3 static website Bucket permissions screenshot

Add Permissions

Buckets by default are not publicly accessible, so we need to change the S3 Bucket Permission. Select the Bucket Policy from the permissions panel.

Add AWS S3 Bucket permission screenshot

Add the following bucket policy into the editor. Where `notes-app-client` is the name of our S3 bucket. Make sure to use the name of your bucket here.
{
"Version":"2012-10-17",
"Statement":[{
"Sid":"PublicReadForGetBucketObjects",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::notes-app-client/*"]
}
]
}

Save bucket policy screenshot

And hit Save.

Enable Static Web Hosting

And finally we need to turn our bucket into a static website. Select the Properties tab from the top panel.

Select properties tab screenshot

Select Static website hosting.

Select static website hosting screenshot

Now select Use this bucket to host a website and add our index.html as the Index Document and the Error Document. Since we are letting React handle 404s, we can simply redirect our errors to our index.html as well. Hit Save once you are done.

This panel also shows us where our app will be accessible. AWS assigns us a URL for our static website. In this case the URL assigned to me is notes-app-client.s3-website-us-east-1.amazonaws.com.

Edit static website hosting properties screenshot

Now that our bucket is all set up and ready, let's go ahead and upload our assets to it.

TODO: Infrastructure as Code Setup with cloudformation.

Documentation for s3 bucket, bucket policy, Ref and the basics.

AWSTemplateFormatVersion: "2010-09-09"
Description: 'Static website hosting with S3 and CloudFront'
Parameters:
DefaultRootObject:
Description: 'The default path for the index document.'
Type: String
Default: 'index.html'
ErrorPagePath:
Description: 'The path of the error page for the website.'
Type: String
Default: 'index.html'
ApplicationName:
Description: 'The name of the application'
Type: String
Default: 'ssk-notes-app-client'
Resources:
# Create the bucket to contain the website HTML
ProdLiveS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub '${ApplicationName}-prod'
WebsiteConfiguration:
IndexDocument: !Ref DefaultRootObject
ErrorDocument: !Ref ErrorPagePath
ReadPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref ProdLiveS3Bucket
PolicyDocument:
Statement:
- Action: 's3:GetObject'
Effect: Allow
Resource: !Sub 'arn:aws:s3:::${ProdLiveS3Bucket}/*'
Principal: '*'
Outputs:
BucketName:
Description: 'S3 Bucket Name'
Value: !Ref ProdLiveS3Bucket

Deploy it in the web CloudFormation UI or in the cli:

aws cloudformation create-stack --stack-name myteststack --template-body file:///home/testuser/mytemplate.json --parameters ParameterKey=Parm1,ParameterValue=test1 ParameterKey=Parm2,ParameterValue=test2