Getting Let's Encrypt Working with Azure Functions
Who this will help?
This will help anyone who falls into the two cases below.
Create an Azure Functions app that has a custom domain, and an SSL certificate from Let’s Encrypt. If you just need SSL you can use the Microsoft URLs for the site.
Create a cheap Static Website with a custom domain and an SSL certificate. Azure Functions can use a consumption model plan to run. A consumption plan only charges you only when you serve up requests. If you create a Static Web site on a storage account to get SSL working you need to setup a CDN, that have a cost, and you will not be able to use Let’s Encrypt. To get around this you can setup an Azure Function app and use thier Proxy functionality to serve up your static web site and use Let’s Encrypt for the SSL and custom domain.
Background
Let’s Encrypt gives you the ability to get an SSL certificate for your website. There are a number of steps to get this working with a Azure Web Application using this link Lets Encrypt site extension. Azure Functions work a little differently so you can use that install document until you get to step “Install the Lets Encrypt Site Extension”. When you get to that step, come back here and we will finish up.
What does this solve?
When you click the button for the Lets Encrypt extension to get a certificate, at some point in the process, it loads a file onto your site that it then requests. Let’s Encrypt puts this file on your site so it can prove the domain is yours. The file is is looking for is at this URL http://yourdomain.com/.well-known/acme-challenge
.
Azure functions can’t serve files without extensions, which that challenge file is. When it can’t get to the file, you get an exception when installing your certificate.
To fix it we need to do a few extra steps.
We will give Let’s Encrypt access to your Storage Account so it can place the file in that folder, then we will create a proxy from your Function App to the Storage Account. The Storage Account can serve files without extensions, and this install will work.
You need to make sure the proxy in the Azure Function URL is gotten from Azure Storage Explorer on the tab below
Getting Started
You need to have done the following steps before using this tutorial. These are documented, and I will not get into how to do these steps here.
- Have an Azure Subscription.
- Create an Azure Function app.
- Have your custom domain name setup and working in Azure. (Azure has good documentation on this).
- (Optional) A Storage account that has the static website enabled. If your using this to get ssl working for a static website, and hopefully the function app and the static web files will be in the same Storage Account or you will need more work in the setup.
Gathering all the Secrets
Your going to need this! Copy the following list of values in notepad. As we navigate Azure to gather all the values we will need, use the list below and paste the values as we go. At the end we will use them all when we fillout all the config info later.
Azure Function\Overview page\Subscription ID
Azure Function\Overview page\Resource Group (name)
Azure Function\Overview page\Azure Function URL
Storage Account\Storage Explorer\LetsEncrypt-challenge Folder
Storage Account\Storage Explorer\LetsEncrypt-challenge Backend URL
Storage Account\Static Website\Primary Endpoint
Storage Account\Access Keys\Connection String
Azure Active Directory\App Registrations\Application (Client) ID
Azure Active Directory\App Registrations\Directory (Tenant) ID
Azure Active Directory\App Registrations\Client Secret
Function App Values
Overview Page Tab
Azure Function\Overview page\Subscription ID = Copy Subscription ID Here
Azure Function\Overview page\Resource Group (name) = Resource Group here
Azure Function\Overview page\Azure Function URL = URL

Storage Account Values
Storage Explorer Tab
You will need to create a folder here named “letsencrypt-challenge” like pictured below.
Storage Account\Storage Explorer\LetsEncrypt-challenge Folder = Hard Code “letsencrypt-challenge” here
Storage Account\Storage Explorer\LetsEncrypt-challenge Backend URL = Select the ‘LetsEncrypt-challenge’ folder and click the “Copy URL” button, and past the URL here.

Static Website Tab
If you don’t have this tab you will need to upgrade your Storage Account to V2. You can do this on the Configuration Tab.
Storage Account\Static Website\Primary Endpoint = Primary Endpoint

Access Keys Tab
Storage Account\Access Keys\Connection String = Key 1 or 2 Connection String value here.

Azure Active Directory
Overview Tab
Go to Azure Active Directory and select the “app registrations” tab and then select the app you created. Once there grab these secrets.
Azure Active Directory\App Registrations\Application (Client) ID = Application (Client) ID
Azure Active Directory\App Registrations\Directory (Tenant) ID = Directory (Tenant) ID

Client Secret Tab
Azure Active Directory\App Registrations\Client Secret = Need to copy this value when you create the secret. If you lost the value you will need to crate a new entry from this page

Putting it all together
Azure Function app configuration page

Add these values to your config file using the values we have gathered in the previous section.
Key | Value - copy to notepad |
---|---|
AzureWebJobsDashboard | Storage Account\Access Keys\Connection String |
AzureWebJobsStorage | Storage Account\Access Keys\Connection String |
letsencrypt:AuthorizationChallengeBlobStorageAccount | Storage Account\Access Keys\Connection String |
letsencrypt:AuthorizationChallengeBlobStorageContainer | Storage Account\Storage Explorer\LetsEncrypt-challenge Folder |
letsencrypt:ClientId | Azure Active Directory\App Registrations\Application (Client) ID |
letsencrypt:ClientSecret | Azure Active Directory\App Registrations\Client Secret |
letsencrypt:ResourceGroupName | Azure Function\Overview page\Resource Group (name) |
letsencrypt:ServicePlanResourceGroupName | Azure Function\Overview page\Resource Group (name) |
letsencrypt:SiteSlot | |
letsencrypt:SubscriptionId | Azure Function\Overview page\Subscription ID |
letsencrypt:Tenant | Azure Active Directory\App Registrations\Directory (Tenant) ID |
letsencrypt:UseIPBasedSSL | false |
Let’s Encrypt extension config values

Add these values to your config file using the values we have gathered in the previous section.
Key | Value - from our notepad |
---|---|
Tenant | Azure Active Directory\App Registrations\Directory (Tenant) ID |
SubscriptionId | Azure Function\Overview page\Subscription ID |
ClientId | Azure Active Directory\App Registrations\Application (Client) ID |
ClientSecret | Azure Active Directory\App Registrations\Client Secret |
ResourceGroupName | Azure Function\Overview page\Resource Group (name) |
ServicePlanResourceGroupName | Azure Function\Overview page\Resource Group (name) |
Azure Proxy settings
Lets Encrypt Proxy
If your here to just get an Azure Function app a custom domain and an SSL certificate, then you just need this proxy. This will Porxy your Let’s Encrypt challenge to the backend URL.

Add these values to your config file using the values we have gathered in the previous section.
Key | Value - from our notepad |
---|---|
Proxy URL | Azure Function\Overview page\Azure Function URL |
Backend URL | Storage Account\Storage Explorer\LetsEncrypt-challenge Backend URL |
Root Proxy
If your here for a Static Website you will still need the Lets Encrypt Proxy above, but you will also need this one as well.

Add these values to your config file using the values we have gathered in the previous section.
Key | Value - our notepad |
---|---|
Proxy URL | Azure Function\Overview page\Azure Function URL |
Backend URL | Storage Account\static website\primary endpoint |