How to host a modern static site on AWS

24th July, 2017

Having finally gotten around to sprucing up the site, seems prudent to bring the tech up to date by moving to HTTPS (and HTTP2) for an unbeatably fast and secure static site. Here is a brief guide and some tips to avoid some annoying pitfalls.

Create a bucket

Go into S3 and create a bucket for the site. Don't use dots in the bucket name because that can cause obscure problems.

Go into the bucket's 'properties' and enable static website hosting. To make the root be a homepage instead of being empty, create an html file called e.g. index.html, upload it to the bucket, and set index.html as the index document. Take a note of the bucket's endpoint (e.g. yourbucketname.s3-website.region.amazonaws.com) for later, and visit the url to check the homepage shows up.

Create a certificate

Go into AWS Certificate Manager to create an SSL/TLS certificate so the site can be loaded securely. Make sure this is in the magic us-east-1 region (this was the first ever region, so occasionally things default to or only work with this region). Add the root domain, then 'add another name' for a wildcard (e.g. example.com then *.example.com). Check the email of the address associated with the domain to validate the certificate and remember to click the button on the page linked from the email.

Create a Cloudfront distribution

Go into Cloudfront (Amazon's CDN) and create a new web distribution. This speeds up the delivery of the static pages, and allows the site to support HTTPS as all self-respecting modern sites do.

Set the origin to the domain of the S3 bucket's endpoint noted earlier so that the distribution knows where to get the static content. Set the SSL certificate to the custom certificate you just created (which Cloudfront should provide as an option). Choose to Redirect HTTP to HTTPS. Set the 'Alternate Domain Names' to your domain with and without www to tell Cloudfront where it can serve content from. Nearly there.

Bonus settings: For extra goodness, set your Cloudfront distribution to 'Use Origin Cache Headers' to enable setting long caching times on cache-busted static assets. Be extra cool and choose 'Use All Edge Locations' so that people in Kuala Lumpur can get the site nice and fast. It costs a little more, but for an average blog like this, that cost is measured in cents. Also, choose to support HTTP2, for delicious multiplexed all-at-onceness (also stop concatenating files, sharding and using sprites).

Now visit the auto-generated xxxx.cloudfront.net url to get the awesome HTTPS & HTTP2 & CDN'd version of the site, and perhaps make a quick trip to Kuala Lumpur to marvel at how quick it loads from there.

Hook it up with Route 53

Go into Route 53 to hook Cloudfront up with the domain. Create a 'hosted zone' for the domain, and copy the nameservers to the custom DNS of whoever manages the domain.

Create an A record aliasing to the domain name of the cloudfront distribution url e.g. xxxx.cloudfront.net. And now once the DNS has propagated, you can go to https://yourdomain.com and get that tasty static content via Cloudfront edge-nodes over HTTPS.

To optionally redirect the www subdomain to the root domain, create a new bucket in S3 with the exact name you want to redirect e.g. www.yourdomain.com - note it has to match the actual domain. Set the properties to 'redirect all requests' to the domain name, and of course choose to use the HTTPS protocol. Make a note of the xxxx.amazonaws.com endpoint of the bucket. Then hop back into Route 53 to create a CNAME for www.yourdomain.com pointing to the bucket's endpoint you just made a note of. And boom! Visiting http://www.yourdomain.com/something will redirect you to https://yourdomain.com/something, and static site nirvana is finally achieved.