Azure Web App with Let's Encrypt Certificate - Powershell Automation

UPDATE Jan 28, 2018

Niiraj Kumar made me aware that there is actually a Web App site extension that gets a Let's Encrypt cert and renews it as needed with a Web Job. You can find the extension here. It is written by a fellow Dane Simon J. K. Pedersen, whom I will buy a beverage of choice if we ever meet. The Bing must have been weak with me because I didn't find that previously. In any case, it is much appreciated and while my little PowerShell script may not have all the bells and whistles of the site extension, it may serve as a starting point for somebody looking to understand the mechanics of getting a Let's Encrypt certificate on an Azure Web App.

Original Blog Post

Azure Web Apps provide a convenient scalable platform for deploying web sites and web applications. You should enable HTTPS (SSL/TLS) on your web sites and if you are using a custom domain name, you will need a certificate.

Certificates are obtained from a Certificate Authority (CA), which in many cases will charge for their services. There is a new CA called Let's Encrypt and it will provide the certificate for free. I am a fan. This service is great. I highly recommend it.

Like all CAs, you will need to provide some sort of challenge response to document that you control the domain you are trying to generate a certificate for. Typically a challenge involves generating specific DNS records or uploading files with specific content to a Web Server hosted at the domain name location. Let's Encrypt enables you to complete this process through a REST API and there are numerous clients that can automate large parts of the process for you. These clients are often intended to run directly on the Web Server hosting the domain, but if you are hosting your web site on an Azure Web App, there is no client that will automate the entire process for you.

I have written a script, which will a) create an Azure Web App, b) generate a certificate from Let's Encrypt, and c) bind the certificate to the Web App with a custom domain name. You can find the script and some instructions in this GitHub repository. The script uses the ACMESharp PowerShell module to interact with the Let's Encrypt CA.

To use the script, clone the GitHub repository and use a command like:

[ps]
.\CreateLetsEncryptWebApp.ps1 -ResourceGroupName "RESOURCE-GROUP-NAME" `
-WebAppName "WEB-APP-NAME" -Fqdn "DOMAIN NAME" -Location "LOCATION" `
-ContactEmail "EMAIL ADDRESS FOR REGISTRATION"
[/ps]

The script fill first create a Resource Group and Web App, if they don't exist already. It will then pause to give you a chance to point a CNAME to the Web App. You should make sure this is completed before continuing or the script will be unable to add the custom domain name to the Web App. After adding the domain name, it will create an ACME vault (if it doesn't exist) and start the challenge/response process. It will complete the challenge by uploading appropriate files to the web app and notify Let's Encrypt to check the challenge response. Once the challenge has been validated, a certificate will be generated and the script will bind it to the Web App.

The code for the entire workflow is contained in the CreateLetsEncryptWebApp.ps1 file, which contains comments throughout. You can use it "as is" if you simply need to stand up a web app with a custom domain name and HTTPS, or you can use it as inspiration for more elaborate workflows. Feel free to use bits and pieces of it as you see fit.

If you run the script on a Web App that already exists, it will simply generate a new certificate, effectively renewing the certificate. Also note that the certificate is stored in C:\temp after the script is complete. You can save it and upload it again. The certificate is valid for 3 months; if you use this workflow in production, you should set up a scheduled job to renew the certificate on a regular basis.

That is it. Let me know if you have questions/comments/suggestions.