How to use Let's Encrypt SSL certificates with Heroku and AWS CloudFront
Earlier this year, Let’s Encrypt launched, first with a closed beta and more recently, a public beta.
This is fabulous news for all concerned (except, probably, for the SSL certificate issuers that charge $$).
Not only does Let’s Encrypt let you create an entire certificate from the command line, but it’s totally free. It’s now entirely possible to automate SSL certificate generation, so worrying about renewing your cert and having to sort it out after it’s already expired (who hasn’t been there?) could be a thing of the past.
How can we actually use this? I thought it might be a useful exercise to put it together with another cheap dev favourite, Heroku, to see if we could get a custom domain setup with an SSL certificate for the price of a cup of tea.
For the sake of this exercise, I’m going to assume that you have your website/app hosted with Heroku under your own custom domain but only on HTTP and not HTTPS.
Cert me up
You’ll need to install the Let’s Encrypt client before you get much further:
git clone https://github.com/letsencrypt/letsencrypt
Once you have that cloned, you’re set and the following should get the ball rolling:
cd letsencrypt
./letsencrypt-auto certonly -a manual -d your.domain.com
That command will prompt you for an email address and whether you accept the T’s & C’s. Once you get past that, you’ll be presented with a challenge that you own the domain by making a specific URL display specific content. Look carefully at the URL it’s trying to check and create the file with that content, on the site you want to create the cert for. Then press Enter to say that it’s ready.
And that’s it - you’ll now have a bunch of SSL certificate files in /etc/letsencrypt/live/your.domain.com
Custom domain
Heroku has an SSL add-on that will let you use an SSL certificate on a custom domain. But it does come at a cost - $20 a month. That’s more than the price of a cup of tea (even a Badamtam First Flush Darjeeling), so we need a cheaper alternative.
Enter AWS CloudFront.
CloudFront is a CDN from Amazon Web Services that amongst other awesome things, lets you upload an SSL certificate to your own custom domain. It’s billed by usage, so for low traffic sites can be quite a cheap alternative. Here are a few quick steps to get you started:
If you don’t already have an AWS account, create one.
Upload your SSL certificate (via the command line):
cd /etc/letsencrypt/live/your.domain.com
aws iam upload-server-certificate --server-certificate-name myapp.com-ssl --certificate-body file://cert.pem --private-key file://privkey.pem --certificate-chain file://chain.pem --path /cloudfront/prod/
(The --path
param must be specified and must include the cloudfront part for it to work with CloudFront)
Next you want to create a CloudFront distribution:
- Log on to the AWS console and head over to the CloudFront area
- Create a Web distribution
- As the
Origin Domain Name
, specify your Heroku URL - your-app.herokuapp.com - Set various options depending on how you want your app to perform - which HTTP methods to accept and how you want the CDN to perform (cheap & low coverage vs expensive and full coverage - I went for cheap!)
- Add your actual domain (not the Heroku URL) as a CNAME (note that this doesn’t set up the CNAME - it just makes it available to serve it).
- Specify your own SSL certificate. Be careful here - if you specify All Clients, you may incur additional monthly charges. I chose the option for clients that support Server Name Indication (SNI) as it was cheaper.
- Click on the “Create Distribution” button.
Once the distribution is deployed (this can take a while), you can now update your DNS record for your domain. Set it to be a CNAME and set it to resolve to CloudFront distribution URL - it’ll be something like dxyz123.cloudfront.net. Give it a while for DNS to propagate and hey presto, you have a valid SSL certificate on a custom domain.
Some things to note
You don’t have to use Heroku for this article to be of use. If you have a domain hosted via S3 (or any Cloud Storage provider of choice for that matter), then you can use the same principle. The same also applies if you have your own server too, all you need is an origin domain and point your CloudFront distribution at it.
On low traffic sites, this is cheap - but the more you use CloudFront, the more it’ll eat into your Christmas party fund. There may come a point where turning on the Heroku SSL add-on may be cheaper. Keep an eye on your AWS charges (Billing & Cost Management) - and optionally set up a billing alert so you know if it’s starting to cost pounds rather than pence. Switch to the Heroku-only solution if it’s getting too expensive.
Let’s Encrypt SSL certificates expire after 90 days - so you’ll need to re-issue them. But seeing as you generate them and upload them to AWS from the command line, it shouldn’t be too difficult to auto-generate them every 3 months!