Go to the profile of  Leo
why do i need a bio? they are painful to write.
7 min read

Setting up Ghost in Azure with Let's Encrypt Part 2

Setting up Ghost in Azure with Let's Encrypt Part 2

When I had my Ghost up and running, the next step is to install Let's Encrypt. Currently there are no Microsoft support for us.

Luckily, early this year, Simon Pedersen, packaged a tool to do the installation for Let's Encrypt.


  • Microsoft Azure Storage Account
  • Microsoft Azure Service Principal
  • Custom Domain

Creating an Azure Storage Account

For more details, please visit official documentation

  • After creating the storage account under the same Resource Group as your web app, go to Application Settings
  • Add AzureWebJobsStorage and set the value similar to DefaultEndpointsProtocol=https;AccountName={storage account name};AccountKey={storage account key}
  • Add AzureWebJobsDashboard and set the value similar to DefaultEndpointsProtocol=https;AccountName={storage account name};AccountKey={storage account key}

Creating a Service Principal

From the wiki of Let's Encrypt Site Extension:

A service principal is a Azure AD entry that can be used for unattended access to Azure resources. You can consider it service account. You need a service principal with Access to your Resource Group(s) in order for the Let's Encrypt site extension to renew your certificate without manual involvement once they expire. The service principal is also used to install the certificate the first time, in order to validate that it is setup correctly.
  • Go to Microsoft Azure Portal, and click browse, and type Active Directory
  • This will open in a new window and open the classic portal.
  • Select the directory that you want to use for creating the new application.

Since I already have an application, I see three items. However, if it's empty, you should see this

  • Select the type of application you would like to create. Select and application my organization is developing
  • Fill in name of the application, this will also become the name of the service principal, and select WEB APPLICATION AND/OR WEB API and click the next button.
  • Fill in the properties for your app. For SIGN-ON URL, provide the URI to a web-site that describes your application. The existence of the web-site is not validated. You can use the url to the web app you want SSL on. For APP ID URI, provide the URI that identifies your application. The uniqueness or existence of the endpoint is not validated.

You have created your application which also creates a service principal for you.

Getting service principal's unique identifier (client id)

The service principal is uniquely identified by its client id to get that, select the Configure tab and copy the CLIENT ID.

Creating a client secret

To setup the credentials for the service principal we must create a key for the application.

  • Click on the Configure tab to configure your application's key (the service principal password).
  • Scroll down to the Keys section and select how long you would like your password to be valid.
  • Select Save to create your key.
Note: The saved key is displayed and you can copy it. You will not be able to retrieve the key later so you will want to copy it now.
  • Your application is now ready and the service principal created on your tenant. When signing in as a service principal be sure to use:
  • CLIENT ID - as your user name.
  • KEY - as your client secret/password.

Grant permissions to the Service Principal

Once the service principal has been created it needs "Contribute" Access to the resource group(s) that contains the App Service Plan and the App Service. If they are in separate resource groups it is important to grant access to both.

You can use the new azure portal to grant access to the service principal.

  • In the portal find the resource group for you App Service and App Service Plan, click the Access button
  • Click Add, and select the Role Contributor
  • Now add the service principal user you created earlier to the role, you can find the service principal by searching for the Application Name you used in step 7 of creating the Service Principal.

Installing Let's Encrypt Site Extension

  • Go to your site's SCM page, the url format is https://{your site name}.scm.azurewebsites.net
  • Go to site extensions, and click gallery, then type Let's Encrypt
  • Once installed, you can click the Launch button and it will open to https://{your site name}scm.azurewebsites.net/letsencrypt/
  • There are a lot of properties that it uses, we can setup the values here, or we can go to our Web App 's Application Settings to store the values.
  • Add the following properties and their values:
  • letsencrypt:Tenant - (This can be found when you're on the portal, click on your profile at the upper right screen, and under directory, it has a template like this) tenantname.onmicrosoft.com
  • letsencrypt:SubscriptionId - Your MSDN Subscription ID
  • letsencrypt:ResourceGroupName - Your Resource Group Name where the Web App lives
  • letsencrypt:ClientId - This is the GUID from Service Principal that you created earlier
  • letsencrypt:ClientSecret - This is the one time chance to copy the key value that you also created earlier

Configuring iisnode to serve Let's Encrypt Files

The tool need to be able to communicate to let's encrypt files, so serve let's encrypt files, so we have to update our web.config to serve it.

  • While on the SCM Portal, go to Debug Console, and navigate to D:\home\site\wwwroot>
  • Open the web.config and update it with the following:
<?xml version="1.0" encoding="utf-8"?>
    <httpErrors existingResponse="PassThrough" />
      <add name="iisnode" path="index.js" verb="*" modules="iisnode"/>
            <rule name="Force HTTPS" enabled="true">
              <match url="(.*)" ignoreCase="false" />
                <add input="{HTTPS}" pattern="off" />
              <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
            <rule name="AcmeContent" patternSyntax="Wildcard">
                <match url=".well-known/acme-challenge/*" />
                <action type="Rewrite" url="{REQUEST_URI}" logRewrittenUrl="true"/>
            <rule name="StaticContent" patternSyntax="Wildcard">
                <action type="Rewrite" url="public/{R:0}" logRewrittenUrl="true"/>
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
                <match url="*.*"/>
            <rule name="DynamicContent">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
                 <action type="Rewrite" url="index.js"/>  
            <rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
                <match serverVariable="RESPONSE_Strict_Transport_Security"
                    pattern=".*" />
                    <add input="{HTTPS}" pattern="on" ignoreCase="true" />
                <action type="Rewrite" value="max-age=31536000" />
  • Go back to the Let's Encrypt Site Extension, and you should see that the values are populated. Click next
  • If you successfully registered your custom domain in your web application, then you should see it under the next page. Click next
  • Select the hostname, and email address, and click request and install certificate
  • At this point, if everything is configured right the certificate should be installed

If you are wondering why it's only A and not A+:

All Windows Servers will be capped at an A rating until support is introduced. Thanks to Nick Lowe for pointing out these changes on Twitter. I will update the article again once this feature is supported in IIS.
Update: Ivan Ristic, creator of the Qualys SSL Test, has confirmed that you can get an A+ by only supporting the TLSv1.2 protocol. This technically means that your server isn't vulnerable to protocol downgrade attacks as there are no protocols to downgrade to! This may not be ideal for everyone and waiting for TLS_FALLBACK_SCSV support may be the only choice. - Scott Helme