Using Let's Encrypt with Azure CDN
As I was in the process of moving this blog from AWS to Azure, I found myself in an interesting position.
Azure CDN can provision a certificate for HTTPS on its own, unless you are using the root domain (ex: esg.dev
), in which case you need to provide your own.
I figured the cheapest way would be to use Let’s Encrypt, since it’s free. And Azure already supports it.
Or does it? It looks like it can provision a certificate automatically for App Services, but not for Azure CDN.
Let’s Encrypt’s certbot can automate this on a number of platforms, but not Azure CDN.
So I had to manually (for now) create a certificate and then configure it on Azure CDN.
These are the steps I took to make it happen.
Creating the certificate with certbot
First, let’s setup certbot.
You will need access to a Linux machine as there is no version of certbot available for Windows yet. In my case, I used Ubuntu on top for WSL, and I based the commands off the Ubuntu documentation page for certbot.
Install certbot
We’ll need to add the certbot PPA:
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
and then install certbot itself
sudo apt-get install certbot
Generate the certificate
Now we can use certbot to generate a new certificate in manual mode.
Note: It’s possible to run certbot without sudo, see https://certbot.eff.org/faq/#does-certbot-require-root-administrator-privileges for more information.
While Let’s Encrypt supports wildcard certificates (ex: *.esg.dev
), I only need www.esg.dev
and esg.dev
, so I’ll be specifying those via the -d
(domain) switch.
We’ll also be using the DNS validation method, which involves adding TXT records to your DNS zone, specifically one for each domain within the certificate.
Now we run the following to launch the certbot wizard.
sudo certbot certonly --cert-name esg.dev --manual -d esg.dev -d www.esg.dev --preferred-challenges dns
Follow the instructions given by certbot.
For each of the domain specified, create the TXT record with the values generated by certbot in your DNS provider of choice. In my case, it was for _acme-challenge.esg.dev
and _acme-challenge.www.esg.dev
.
Certbot will verify those records. If the validation fails, you might need to re-start the generation process.
This will have generated pem files for your domain, in my case, under /etc/letsencrypt/live/esg.dev/
.
We still have one more step to take. Azure CDN didn’t like it when I tried to use the pem files, so let’s convert those to pfx to make our life a bit easier. We can do this with OpenSSL:
sudo pkcs12 -export -inkey /etc/letsencrypt/live/esg.dev/privkey.pem -in /etc/letsencrypt/live/esg.dev/fullchain.pem -name esg-dev -out esg.pfx
This will prompt you for a password, enter whatever you feel is appropriate.
you now can upload the generated pfx file to an Azure key vault, which will allow you to configure Azure CDN with a custom certificate.
Renewing the certificate
Let’s Encrypt certificates have an expiry of 90 days.
To renew the certificate, it’s important to remember that certbot’s renew
command is meant for non-interactive usage, and won’t work out of the box with the manual plugin.
But all we need to do is re-run the same exact command as we did the first time:
sudo certbot certonly --cert-name esg.dev --manual -d esg.dev -d www.esg.dev --preferred-challenges dns
And then convert/upload the new certificate to your vault. You’ll also need to update your custom domains in Azure CDN to use the newer version of the certificate.
Next steps
There are a few solutions out there to do this, but I’ve had had no real luck getting them working, and I wanted to understand the process by doing it manually first anyway.
I’ll be looking at automating this in the near future as I’ll probably forget to do this every 90 days, so stay tuned!