9
votes

I am deploying an Azure Front Door via an ARM template, and attempting to enable HTTPS on a custom domain.

According to the Azure documentation for Front Door, there is a quick start template to "Add a custom domain to your Front Door and enable HTTPS traffic for it with a Front Door managed certificate generated via DigiCert." However, while this adds a custom domain, it does not enable HTTPS.

Looking at the ARM template reference for Front Door, I can't see any obvious way to enable HTTPS, but perhaps I'm missing something?

Notwithstanding the additional information below, I'd like to be able to enable HTTPS on a Front Door custom domain via an ARM template deployment. Is this possible at this time?

Additional information

Note that there is a REST operation to enable HTTPS, but this does not seem to work with a Front Door managed certificate -

POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/frontDoors/{frontDoorName}/frontendEndpoints/{frontendEndpointName}/enableHttps?api-version=2019-05-01
{
    "certificateSource": "FrontDoor",
    "protocolType": "ServerNameIndication",
    "minimumTLSVersion": "1.2"
}

There is also a Az PowerShell cmdlet to enable HTTP, which does work.

Enable-AzFrontDoorCustomDomainHttps -ResourceGroupName "lmk-bvt-accounts-front-door" -FrontDoorName "my-front-door" -FrontendEndpointName "my-front-door-rg"
4
have you tried adding an enableHttps section inside the frontendEndpoint properties ? if you add the enablehttps section with the content of the rest body it may work, also change the api version inside the arm to be 2019-05-01.Thomas
@Thomas, thanks for your reply. Where are you finding this documentation? According to the ARM template docs, the latest version is 2019-04-01.David Gard
I mean ARM template is just wrapper around the REST API so the documentation may not be up to date. If something is available through REST API, ti should be available through ARM.Thomas
What you can try is doing it manually then export your resource group ARM template to see if you can find the enablehttps section (reverse engineering). You can also tr using the ARMClient to discover the ARM schema to enable httpsThomas
I've tried exporting, and 2019-04-01 is used, with no reference to enableHttps. Will try using 2019-05-01 and see what happens...David Gard

4 Answers

5
votes

UPDATE: This implementation currently seems to be unstable and is working only intermittently, which indicates it may not be production ready yet.

This now actually seems to be possible with ARM templates, after tracking down the latest Front Door API (2020-01-01) specs (which don't appear to be fully published in the MS reference websites yet):

https://github.com/Azure/azure-rest-api-specs/tree/master/specification/frontdoor/resource-manager/Microsoft.Network/stable/2020-01-01

There's a new customHttpsConfiguration property in the frontendEndpoint properties object:

"customHttpsConfiguration": {
  "certificateSource": "AzureKeyVault" // or "FrontDoor",        
  "minimumTlsVersion":"1.2",
  "protocolType": "ServerNameIndication",

  // Depending on "certificateSource" you supply either:
  "keyVaultCertificateSourceParameters": {
    "secretName": "<secret name>",
    "secretVersion": "<secret version>",
    "vault": {
      "id": "<keyVault ResourceID>"
    }
  }

  // Or:
  "frontDoorCertificateSourceParameters": {
    "certificateType": "Dedicated"
  }
}

KeyVault Managed SSL Certificate Example

Note: I have tested this and appears to work.

    {
      "type": "Microsoft.Network/frontdoors",
      "apiVersion": "2020-01-01",
      "properties": {
        "frontendEndpoints": [
         {
            "name": "[variables('frontendEndpointName')]",
            "properties": {
              "hostName": "[variables('customDomain')]",
              "sessionAffinityEnabledState": "Enabled",
              "sessionAffinityTtlSeconds": 0,
              "webApplicationFirewallPolicyLink": {
                "id": "[variables('wafPolicyResourceId')]"
              },
              "resourceState": "Enabled",
              "customHttpsConfiguration": {
                "certificateSource": "AzureKeyVault",        
                "minimumTlsVersion":"1.2",
                "protocolType": "ServerNameIndication",
                "keyVaultCertificateSourceParameters": {
                  "secretName": "[parameters('certKeyVaultSecret')]",
                  "secretVersion": "[parameters('certKeyVaultSecretVersion')]",
                  "vault": {
                    "id": "[resourceId(parameters('certKeyVaultResourceGroupName'),'Microsoft.KeyVault/vaults',parameters('certKeyVaultName'))]"
                  }
                }
              }
            }
          }
        ],
        ...
      }
    }

Front Door Managed SSL Certificate Example

Looks like for a FrontDoor managed certificate you would need to set:

Note: I have not tested this

    {
      "type": "Microsoft.Network/frontdoors",
      "apiVersion": "2020-01-01",
      "properties": {
        "frontendEndpoints": [
         {
            "name": "[variables('frontendEndpointName')]",
            "properties": {
              "hostName": "[variables('customDomain')]",
              "sessionAffinityEnabledState": "Enabled",
              "sessionAffinityTtlSeconds": 0,
              "webApplicationFirewallPolicyLink": {
                "id": "[variables('wafPolicyResourceId')]"
              },
              "resourceState": "Enabled",
              "customHttpsConfiguration": {
                "certificateSource": "FrontDoor",        
                "minimumTlsVersion":"1.2",
                "protocolType": "ServerNameIndication",
                "frontDoorCertificateSourceParameters": {
                  "certificateType": "Dedicated"
                }
              }
            }
          }
        ],
        ...
      }
    }
0
votes

I was able to successfully make an enableHttps REST Call using the Azure Management API.

I got a successful response and can see the resource results in the portal.azure.com and resource.azure.com sites. However I am pretty sure the Management API, and PowerShell methods are the only ways supported right now. Since there is likely some validation required on the Certificate and Handling, they didn't include that yet in the ARM Templates. Given validation can be quite important, it is best you confirm your configuration is workable in the UI first, before automating it (IMHO).

0
votes

According to this discussion this seems only possible via the REST API (see e.g. this answer) and not (yet) via ARM.

0
votes

I managed to get this working with an ARM template. The below link shows you how to do this using Azure Front Door as a certificate source: https://github.com/Azure/azure-quickstart-templates/blob/master/101-front-door-custom-domain/azuredeploy.json

I drew inspiration from this for deploying a certificate from Azure Key Vault for a custom domain. Here are the relevant elements from the ARM template that I am using:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "hubName": {
            "type": "string",
            "metadata": {
                "description": "Name to assign to the hub. This name will prefix all resources contained in the hub."
            }
        },
        "frontdoorName": {
            "type": "string",
            "metadata": {
                "description": "Name to assign to the Frontdoor instance"
            }
        },
        "frontdoorCustomDomain": {
            "type": "string",
            "metadata": {
                "description": "The custom domain name to be applied to the provisioned Azure Frontdoor instance"
            }
        },
        "keyVaultCertificateName": {
            "type": "string",
            "metadata": {
                "description": "Name of the TLS certificate in the Azure KeyVault to be deployed to Azure Frontdoor for supporting TLS over a custom domain",
                "assumptions": [
                    "Azure KeyVault containing the TLS certificate is deployed to the same resource group as the resource group where Azure Frontdoor will be deployed to",
                    "Azure KeyVault name is the hub name followed by '-keyvault' (refer to variable 'keyVaultName' in this template)"
                ]
            }
        },
        ...
    },
    "variables": {
        "frontdoorName": "[concat(parameters('hubName'), '-', parameters('frontdoorName'))]",
        "frontdoorEndpointName": "[concat(variables('frontdoorName'), '-azurefd-net')]",
        "customDomainFrontdoorEndpointName": "[concat(variables('frontdoorName'), '-', replace(parameters('frontdoorCustomDomain'), '.', '-'))]",
        "keyVaultName": "[concat(parameters('hubName'), '-keyvault')]",
        "frontdoorHostName": "[concat(variables('frontdoorName'), '.azurefd.net')]",
        ...
    },
    "resources": [
        {
            "type": "Microsoft.Network/frontdoors",
            "apiVersion": "2020-05-01",
            "name": "[variables('frontdoorName')]",
            "location": "Global",
            "properties": {
                "resourceState": "Enabled",
                "backendPools": [...],
                "healthProbeSettings": [...],
                "frontendEndpoints": [
                    {
                        "id": "[concat(resourceId('Microsoft.Network/frontdoors', variables('frontdoorName')), concat('/FrontendEndpoints/', variables('frontdoorEndpointName')))]",
                        "name": "[variables('frontdoorEndpointName')]",
                        "properties": {
                            "hostName": "[variables('frontdoorHostName')]",
                            "sessionAffinityEnabledState": "Enabled",
                            "sessionAffinityTtlSeconds": 0,
                            "resourceState": "Enabled"
                        }
                    },
                    {
                        "id": "[concat(resourceId('Microsoft.Network/frontdoors', variables('frontdoorName')), concat('/FrontendEndpoints/', variables('customDomainFrontdoorEndpointName')))]",
                        "name": "[variables('customDomainFrontdoorEndpointName')]",
                        "properties": {
                            "hostName": "[parameters('frontdoorCustomDomain')]",
                            "sessionAffinityEnabledState": "Enabled",
                            "sessionAffinityTtlSeconds": 0,
                            "resourceState": "Enabled"
                        }
                    }
                ],
                "loadBalancingSettings": [...],
                "routingRules": [...],
                "backendPoolsSettings": {
                    "enforceCertificateNameCheck": "Enabled",
                    "sendRecvTimeoutSeconds": 30
                },
                "enabledState": "Enabled",
                "friendlyName": "[variables('frontdoorName')]"
            }
        },
        {
            "type": "Microsoft.Network/frontdoors/frontendEndpoints/customHttpsConfiguration",
            "apiVersion": "2020-07-01",
            "name": "[concat(variables('frontdoorName'), '/', variables('customDomainFrontdoorEndpointName'), '/default')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/frontdoors', variables('frontdoorName'))]"
            ],
            "properties": {
                "protocolType": "ServerNameIndication",
                "certificateSource": "AzureKeyVault",
                "minimumTlsVersion": "1.2",
                "keyVaultCertificateSourceParameters": {
                    "secretName": "[parameters('keyVaultCertificateName')]",
                    "vault": {
                        "id": "[resourceId(resourceGroup().name, 'Microsoft.KeyVault/vaults', variables('keyVaultName'))]"
                    }
                }
            }
        }
    ]
}