How to serve an AWS static website with CloudFront distribution (using console / CloudFormation template)

James Li
6 min readOct 5, 2020

--

Introduction

In part 1 of this mini project, we looked at how to connect to websocket, stream top-of-book data and visualise it locally.
This part of the mini project looks at the various ways we can host our visualisation on a static website on AWS.

Part 1’s finished product, streaming top of book price from Coinbase

AWS provides a simple solution that allows us to host static website within minutes. This AWS S3 documentation provides a nice guide, which you may follow. However, there are a couple of improvements we can make:

  • what if you don’t want to expose your bucket name?
  • or you don’t want public access to the objects in your S3 bucket?
  • or you want your website to use HTTPS?
S3 bucket static website, hosted on HTTP, and showing the bucket name

We can use CloudFront instead to host our website, granting it access, instead of allowing public access to the bucket objects directly.

CloudFront is AWS’s CDN to speed up content delivery; you can also use it with WAF to whitelist / blacklist IPs and more…

In this guide, we will work through the steps to:

(Option 1) Using the AWS console to create CloudFront distribution on an existing S3 bucket

(Option 2) using CloudFormation template to set up the S3 bucket and create the CloudFront distribution, all in one stack

The advantage of using CloudFormation over the 1st option of doing it step by step is that you can create resources, monitor and delete them all within a few clicks, or using a single command line.
Moreover, it helps to keep track of the all resource you’ve created; you can easily replicate the same procedure over and over again, without having to remember all the individual components, and worry about forgetting to delete some of them afterwards.

Option 1: Using the AWS console

(If applicable) If you have previously granted public access to your S3 bucket, turn on the block all public access, and delete the bucket public read bucket policy.

Tick “Block all public access” and save
And delete previously created public read bucket policy

In your S3 bucket page, it should now show “Bucket and objects not public”

(end of if applicable)

  1. On the CloudFront Distribution page on the AWS console, click Create Distribution

2. Select Get Started under the Web delivery method (Not RTMP)

3. In the Create Distribution step:

  • For Origin Domain Name, choose the existing S3 bucket that you want to host your static website;
  • For Restrict Bucket Access, select “Yes”;
  • For Origin Access Identity, select “Create a New Identity”
  • Select “Yes” to Grant Read Permission on Bucket — This will create a bucket policy to allow CloudFront access

4. Under Default Cache Behavior Settings

  • Viewer Protocol Policy, select “Redirect HTTP to HTTPS”

5. Leave the rest as default and click Create Distribution at the bottom of the page

And…that’s it! Head back to the CloudFront Distributions page, you should now find that the deployment is In Progress. It should take no longer than 5-10 minutes.

CloudFront deployment in progress

Once it’s deployed, you can see the status is change to Deployed

Feel free to go to your {CloudFrontDomain}/index.html or whatever document you’d like to fetch and there you have it!

Example:
https://d36ugnpyhre46t.cloudfront.net/top-of-book-streaming/coinbase.html

6. Cleaning up

To delete the CloudFront Distrbution, select your distribution, and Disable the distribution. Once it’s disabled, the greyed out Delete button will become available.

In addition, you may also want to clean up the associated origin access identity, located under Security in the navigation bar on the left, on the CloudFront console.

And the S3 Bucket Policy created.

Option 2: Using CloudFormation template

As mentioned above, the advantage of using CloudFormation is that it is easier to create, delete and keep track of your resources. I have created a template you may use. (Snippet also in Appendix)

The template does the following:

  • Creates a S3 bucket, and a bucket policy for CloudFront to access it
  • Creates a CloudFront Origin Access Identity
  • Creates a CloudFront distribution for the S3 bucket

There are two user input parameters we will have specified here are:

  1. The S3 bucket name
  2. The name of the HTML index document (e.g. index.html)

After the resources are created, you may upload your static website files to the S3 bucket created.

To create the CloudFormation stack, you may use AWS CLI or the console:

Via AWS CLI:

aws cloudformation create-stack --stack-name YOUR_STACK_NAME \
--template-body file://YOUR_TEMPLATE_FILE_PATH.json \
--parameters ParameterKey=S3BucketName,ParameterValue=BUCKET_NAME \
ParameterKey=S3BucketIndexDocument,ParameterValue=YOUR_INDEX.html

After the resources are created, upload your static website contents to the newly created S3 bucket and that’s all!

To see the output of the stack (bucket name, OAI ID, and the CloudFront website URL):

aws cloudformation describe-stacks --stack-name YOUR_STACK_NAME

To clean up and delete the stack:

aws cloudformation delete-stack --stack-name YOUR_STACK_NAME

Note: We have specified the S3 bucket deletion policy as retain, so you’ll need to delete the bucket yourself if you want to do so.

Via CloudFormation console:

  1. Head to CloudFormation console and click Create stack and upload the template

2. Enter a stack name, your S3 bucket index document and a of your bucket name of your choice

3. Customise other settings if you wish and click Create stack

4. Return to the CloudFormation Stacks page, you should now see that your stack is CREATE_IN_PROGRESS

Inspecting the Events tab, you can see the events in detail

Once the stack is created, you can head to the Outputs tab to get your website URL.

5. Similar to before, upload your static website contents to the newly created S3 bucket and there you have it!

To clean up, simply delete the stack and CloudFormation will do the rest for you (except the S3 bucket, where deletion policy is set to retain).

Summary

In Part 1 of this mini-project, we explored how to connect to websocket and stream top-of-(order)-book data and visualise it real time using a Chart.js streaming plugin.

Separately, in this blog post, we have explored reasons for why we may want to use CloudFront to host our website instead of the S3 bucket static website endpoint; how to create a S3 website with CloudFront distribution, using either the console, or a CloudFormation template.

We have also explained briefly why using CloudFormation is neater and how you may go about deploying the stack, using AWS CLI or the CloudFormation console.

I hope you enjoyed this 2 part mini-project!

Appendix

--

--