I decided make some updates to my website today, mostly behind the scenes. The biggest change was changing my static website build to use Gulp which involved some code rewrites. I also added paginiation, which is only really relevant if I start posting more, and tweaked some styles. The biggest user facing improvement I made was enabling HTTPS.
Ever since I started following the Let's Encrypt project, I've been meaning to enable TLS on my site. Why use TLS on a static website? well I don't really have a good reason for that but I have no problem with going over the top on privacy just because. Let's Encrypt, does have some overhead. It requires executing a script often, since the certificates expire after a short time. You might suspect from my posting frequency that I'd like something that requires a little less maintenance.
Lucky for me, I quickly discovered that AWS recently announced a way to get free certificates with a new service, AWS ACM. This site was already hosted on AWS, using the recommended method. The setup required to use ACM for a static site was a bit different.
Step 1: S3 Buckets
In my previous setup, I needed a bucket that was named the same as my website. The new method requires using CloudFront, so the bucket name is not as important. That domain named bucket is useful though, for redirecting traffic from the apex domain. CloudFront requires using a CNAME, and apparently acceding to RFC1033 a CNAME cannot be used by an apex domain. This means you will not be able to have a URL like "https://hyperbolictangents.com".
I moved the contents of my "hyperbolictangents.com" bucket to a new bucket "www-hyperbolictangents-com", then changed the Static Website Settings to redirect to "www.hyperbolictangents.com" (the URL I will be using). If you are not hosting your new S3 bucket in the standard region, it is useful to not use dots in the name. There may be a short time when your CloudFront distribution will do a 307 redirect to the S3 bucket with a URL like: "BUCKET-NAME.s3-website-us-west-2.amazonaws.com" and having dots in the name will cause the SSL certificate be invalid (since the broswer will read your bucketname as multiple sub-domains).
Step 2: CloudFront Distribution
Next, create a CloudFront distribution and point it to your new bucket. The settings that I used:
- Viewer Protocol Policy: Redirect HTTP to HTTPS
- Default TTL: 0 (So I can see my changes immediately)
- Compress Objects Automatically: Yes (use gzip to serve assets)
- Alternate Domain Names: www.hyperbolictangents.com
- SSL Certificate: Custom SSL Certificate
- Click the button to Request an ACM certificate and follow the prompts. You will be sent an Email to confirm domain ownership, so make sure your whois information is right.
- Default Root Object: index.html (object that loads when you go to the root)
I also found it useful to setup an Error page for 403 errors to redirect to my 404.html page. This is the error you get when you try to acces an object in the bucket that does not exist, so prevents users from seeing the S3 error messages (example).
Step 3: Route 53
Finally, I had to modify my Route 53 settings from my hosted zone.
- Point "hyperbolictangents.com" to the Alias of my bucket "hyperbolictangents.com"
- Point "www.hyperbolictangents.com" to the CloudFront distribution
So that was easy. I ran into a few issues putting wrong settings and trying to test things before my distribution updated, but overall pretty painless. So here's what happens now: