Amazon S3 + Amazon Cloudfront is an amazing setup for deploying static websites like Jekyll blogs. Amazon also allows you to secure your Cloudfront website with free SSL certificates! However, Amazon Certicate Manager (the service the generates the certificates) doesn’t play well with custom domains registered through Amazon itself (because of limitations of Amazon Route 53). While this is unfortunate, this post will show how to use Let’s Encrypt as backup solution. The only drawback is that Let’s Encrypt requires you to renew your certificates every three months, while Amazon Certicate Manager doesn’t. Annoying, but we can live with it.

Say Hello to certbot-s3front

There are many reasons why Let’s Encrypt is awesome. One of them is that everyone can create a plugin that generates certificates for a specific type of deployment. And has someone created a plugin for Cloudfront websites? Of course! certbot-s3front is a third party plugin that generates and installs Let’s Encrypt certificates for Cloudfront websites.

Assuming that you have a Cloudfront distribution that serves an S3 static website over a custom domain, the following are the steps required to get a Let’s Encrypt certificate for that custom domain.

Step 1

Install certbot-s3front and, of course, certbot (the official Let’s Encrypt client).

The former can be installed via pip (for archlinux users, I created an AUR package), while certbot should be available in the repositories of most Linux distros.

Step 2

You need to create an IAM policy in your AWS account. Use this template and just replace the name of your bucket in the policy. Important: don’t forget to attach your AWS user to the new policy! Otherwise you’ll get an authentication error later. You can do this in the “Attached Entities” tab in the IAM console.

Step 3

Finally, you need to run the certbot plugin to generate the SSL certificate. I use the following script:

#!/bin/sh

export AWS_ACCESS_KEY_ID="<REPLACE_WITH_YOUR_KEY>"
export AWS_SECRET_ACCESS_KEY="<REPLACE_WITH_YOUR_SECRET>"

certbot --agree-tos -a certbot-s3front:auth \
--certbot-s3front:auth-s3-bucket <REPLACE_WITH_YOUR_BUCKET_NAME> \
--certbot-s3front:auth-s3-region eu-central-1 \
-i certbot-s3front:installer \
--certbot-s3front:installer-cf-distribution-id <REPLACE_WITH_YOUR DISTRIBUTION_ID> \
-d <REPLACE_WITH_YOUR_DOMAIN_NAME>

The certbot client needs root access, so you will have to run the script with:

sudo bash -c <scriptname.sh>

Once the plugin is done, you should see the certificate available from the settings of your distribution, ready to be used. To renew the certificate, just run the script again.

Note that my bucket lives in the eu-central-1 region. If you are using the default us-east-1 region instead, you can remove the --certbot-s3front:auth-s3-region switch from the script (since it’s only necessary for non-default regions).