AWS Static Site

Updated / aws, hugo, blogging

Table of Contents - Infrastructure as Code #

  1. Intro
  2. AWS Static Site: Cloudformation
  3. AWS Static Site: Terraform
  4. AWS Static Site: CDK

Intro #

When I began my blog this year I decided to host it on AWS. Since I'm using Hugo to generate the site, the infrastructure backing it can be very simple. AWS S3 has a static website hosting feature that is ideal for a blog generated by Hugo and AWS Route53 is the natural place to create a CNAME record for the blog's friendly URL. This infrastructure will be simple to manage and extremely inexpensive.

AWS S3 Static Website Hosting #

The majority of the information needed to host a static website on S3 comes from these two pages in the AWS docs:

After enabling static website hosting on an S3 bucket AWS creates a website endpoint that differs from the normal REST endpoint used to interact with the bucket. Compare:

http://<bucket-name>.s3-website-us-east-1.amazonaws.com1

https://<bucket-name>.s3.us-east-1.amazonaws.com

Website endpoints have a few limitations:

  1. they do not support HTTPS
  2. in order to use a CNAME to give our bucket a friendlier DNS name, the bucket name and the CNAME must match2
  3. the bucket content must be publicly accessible

The main point of using an S3 website endpoint is that a bucket configured for static website hosting will redirect requests for the root and for subfolders to an index document and will redirect requests that do not match any file to an error document. These redirection features enable the bucket to work seamlessly with Hugo's pretty URL's. By default, Hugo will put each post in a folder named for that post and containing a file named index.html. Setting the index document to "index.html" in the static web site configuration in S3 will cause S3 to serve up the index.html file when the folder is requested. Most Hugo themes will render a 404.html file into the root of the generated site. Setting the custom error document to "404.html" in the configuration will cause S3 to serve up that file instead of an ugly XML formatted Access Denied page whenever a non-existent page is requested.

AWS CloudFront #

Most browsers will show that sites loaded without using HTTPS are "Not Secure". One way to remove that warning is to put CloudFront in front of your S3 bucket and configure it to use a free SSL certificate from Certificate Manager. Using a CDN like CloudFront has a lot of benefits, including caching your content closer to your visitors, but by default CloudFront will use the normal REST endpoint to point at your bucket. This prevents the redirection features for your index.html and 404.html from working. A blog post by Steve Papa points out that you can change the CloudFront configuration to use the website endpoint for your bucket instead of the REST endpoint to get the best of both worlds:

This solution is pretty nifty, but some Stack Overflow commenters point out that the content remains accessible without going through CloudFront and could potentially be indexed by search engines twice, which is bad for SEO (if you care about such things).3. Disabling public access to the S3 bucket and allowing only CloudFront to access it requires abandoning the static website feature of S3 and using CloudFront Functions to rewrite requests for folders to add index.html.4

Infrastructure as Code #

The next few blog posts will show how to setup a static site and publish a Hugo blog to it using CloudFormation, Terraform, and the AWS Cloud Development Kit. At the end we'll be able to compare the ways to automate this small bit of AWS infrastructure.