Add quickstart - Front Door Standard/Premium with custom domain and customer-managed TLS certificate (#12239)

* Add first draft

* Updates

* Updates

* Update wording

* Move to Microsoft.Cdn folder

* Update readme

* Transpile

* Update metadata
diff --git a/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/README.md b/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/README.md
new file mode 100644
index 0000000..a84a8e6
--- /dev/null
+++ b/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/README.md
@@ -0,0 +1,49 @@
+# Front Door Standard/Premium with custom domain and customer-managed TLS certificate
+
+![Azure Public Test Date](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/PublicLastTestDate.svg)
+![Azure Public Test Result](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/PublicDeployment.svg)
+
+![Azure US Gov Last Test Date](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/FairfaxLastTestDate.svg)
+![Azure US Gov Last Test Result](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/FairfaxDeployment.svg)
+
+![Best Practice Check](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/BestPracticeResult.svg)
+![Cred Scan Check](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/CredScanResult.svg)
+
+![Bicep Version](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/BicepVersion.svg)
+
+[![Deploy To Azure](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazure.svg?sanitize=true)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Fmaster%2Fquickstarts%2Fmicrosoft.cdn%2Ffront-door-standard-premium-custom-domain-customer-certificate%2Fazuredeploy.json)  [![Visualize](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/visualizebutton.svg?sanitize=true)](http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Fmaster%2Fquickstarts%2Fmicrosoft.cdn%2Ffront-door-standard-premium-custom-domain-customer-certificate%2Fazuredeploy.json)
+[![Visualize](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/visualizebutton.svg?sanitize=true)](http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Fmaster%2Fquickstarts%2Fmicrosoft.cdn%2Ffront-door-standard-premium-custom-domain-customer-certificate%2Fazuredeploy.json)
+
+This template deploys a Front Door Standard/Premium with a custom domain and customer-managed TLS certificate.
+
+## Sample overview and deployed resources
+
+This sample template creates a Front Door profile with a custom domain and a customer-managed TLS certificate. To keep the sample simple, Front Door is configured to direct traffic to a static website configured as an origin, but this could be [any origin supported by Front Door](https://docs.microsoft.com/azure/frontdoor/standard-premium/concept-origin).
+
+The following resources are deployed as part of the solution:
+
+### Front Door Standard/Premium
+- Front Door profile, endpoint, origin group, origin, and route to direct traffic to the static website.
+  - Note that you can use either the standard or premium Front Door SKU for this sample. By default, the standard SKU is used.
+- Front Door secret, which refers to a Key Vault secret containing the TLS certificate to use.
+- Front Door custom domain, which refers to the Front Door secret.
+
+## Deployment steps
+
+You can click the "deploy to Azure" button at the beginning of this document or follow the instructions for command line deployment using the scripts in the root of this repo.
+
+## Usage
+
+### Connect
+
+After you deploy the Azure Resource Manager template, you need to validate your ownership of the custom domain by updating your DNS server. You must create a TXT record with the name specified in the `customDomainValidationDnsTxtRecordName` deployment output, and use the value specified in the `customDomainValidationDnsTxtRecordValue` deployment output. You must the validation before the time specified in the `customDomainValidationExpiry` deployment output.
+
+Front Door validates your domin ownership and updates the status automatically. You can monitor the validation process, or trigger an immediate validation, in the domain configuration in the Azure portal.
+
+Next, you should configure your DNS server with a CNAME record to direct the traffic to Front Door. You must create a CNAME record at the host name you specified in the `customDomainName` deployment parameter, and use the value specified in the `frontDoorEndpointHostName` deployment output.
+
+You can then access the Front Door endpoint by using your custom domain name. If you access the hostname you should see a page saying _Welcome_. If you see a different error page, wait a few minutes and try again.
+
+## Notes
+
+- You must grant Front Door access to your key vault before it can access your certificate. [Follow the guidance here](https://docs.microsoft.com/azure/frontdoor/standard-premium/how-to-configure-https-custom-domain#using-your-own-certificate) to register the Azure Front Door application with your Azure Active Directory tenant, and grant Azure Front Door access to your key vault.
diff --git a/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/azuredeploy.json b/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/azuredeploy.json
new file mode 100644
index 0000000..963ca68
--- /dev/null
+++ b/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/azuredeploy.json
@@ -0,0 +1,226 @@
+{
+  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+  "contentVersion": "1.0.0.0",
+  "metadata": {
+    "_generator": {
+      "name": "bicep",
+      "version": "0.4.1301.36686",
+      "templateHash": "1851009544141537410"
+    }
+  },
+  "parameters": {
+    "endpointName": {
+      "type": "string",
+      "defaultValue": "[format('afd-{0}', uniqueString(resourceGroup().id))]",
+      "metadata": {
+        "description": "The name of the Front Door endpoint to create. This must be globally unique."
+      }
+    },
+    "skuName": {
+      "type": "string",
+      "defaultValue": "Standard_AzureFrontDoor",
+      "allowedValues": [
+        "Standard_AzureFrontDoor",
+        "Premium_AzureFrontDoor"
+      ],
+      "metadata": {
+        "description": "The name of the SKU to use when creating the Front Door profile."
+      }
+    },
+    "originHostName": {
+      "type": "string",
+      "metadata": {
+        "description": "The host name that should be used when connecting from Front Door to the origin."
+      }
+    },
+    "customDomainName": {
+      "type": "string",
+      "metadata": {
+        "description": "The custom domain name to associate with your Front Door endpoint."
+      }
+    },
+    "certificateKeyVaultResourceGroupName": {
+      "type": "string",
+      "defaultValue": "[resourceGroup().name]",
+      "metadata": {
+        "description": "The name of the resource group that contains the key vault with custom domain's certificate."
+      }
+    },
+    "certificateKeyVaultName": {
+      "type": "string",
+      "metadata": {
+        "description": "The name of the Key Vault that contains the custom domain's certificate."
+      }
+    },
+    "certificateKeyVaultSecretName": {
+      "type": "string",
+      "metadata": {
+        "description": "The name of the Key Vault secret that contains the custom domain's certificate."
+      }
+    },
+    "certificateKeyVaultSecretVersion": {
+      "type": "string",
+      "defaultValue": "",
+      "metadata": {
+        "description": "The version of the Key Vault secret that contains the custom domain's certificate. Set the value to an empty string to use the latest version."
+      }
+    }
+  },
+  "variables": {
+    "profileName": "MyFrontDoor",
+    "originGroupName": "MyOriginGroup",
+    "originName": "MyOrigin",
+    "routeName": "MyRoute",
+    "secretName": "MySecret",
+    "customDomainResourceName": "[replace(parameters('customDomainName'), '.', '-')]"
+  },
+  "resources": [
+    {
+      "type": "Microsoft.Cdn/profiles",
+      "apiVersion": "2020-09-01",
+      "name": "[variables('profileName')]",
+      "location": "global",
+      "sku": {
+        "name": "[parameters('skuName')]"
+      }
+    },
+    {
+      "type": "Microsoft.Cdn/profiles/afdEndpoints",
+      "apiVersion": "2020-09-01",
+      "name": "[format('{0}/{1}', variables('profileName'), parameters('endpointName'))]",
+      "location": "global",
+      "properties": {
+        "originResponseTimeoutSeconds": 240,
+        "enabledState": "Enabled"
+      },
+      "dependsOn": [
+        "[resourceId('Microsoft.Cdn/profiles', variables('profileName'))]"
+      ]
+    },
+    {
+      "type": "Microsoft.Cdn/profiles/originGroups",
+      "apiVersion": "2020-09-01",
+      "name": "[format('{0}/{1}', variables('profileName'), variables('originGroupName'))]",
+      "properties": {
+        "loadBalancingSettings": {
+          "sampleSize": 4,
+          "successfulSamplesRequired": 3
+        },
+        "healthProbeSettings": {
+          "probePath": "/",
+          "probeRequestType": "HEAD",
+          "probeProtocol": "Http",
+          "probeIntervalInSeconds": 100
+        }
+      },
+      "dependsOn": [
+        "[resourceId('Microsoft.Cdn/profiles', variables('profileName'))]"
+      ]
+    },
+    {
+      "type": "Microsoft.Cdn/profiles/secrets",
+      "apiVersion": "2020-09-01",
+      "name": "[format('{0}/{1}', variables('profileName'), variables('secretName'))]",
+      "properties": {
+        "parameters": {
+          "type": "CustomerCertificate",
+          "useLatestVersion": "[equals(parameters('certificateKeyVaultSecretVersion'), '')]",
+          "secretVersion": "[parameters('certificateKeyVaultSecretVersion')]",
+          "secretSource": {
+            "id": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('certificateKeyVaultResourceGroupName')), 'Microsoft.KeyVault/vaults/secrets', parameters('certificateKeyVaultName'), parameters('certificateKeyVaultSecretName'))]"
+          }
+        }
+      },
+      "dependsOn": [
+        "[resourceId('Microsoft.Cdn/profiles', variables('profileName'))]"
+      ]
+    },
+    {
+      "type": "Microsoft.Cdn/profiles/customDomains",
+      "apiVersion": "2020-09-01",
+      "name": "[format('{0}/{1}', variables('profileName'), variables('customDomainResourceName'))]",
+      "properties": {
+        "hostName": "[parameters('customDomainName')]",
+        "tlsSettings": {
+          "certificateType": "CustomerCertificate",
+          "minimumTlsVersion": "TLS12",
+          "secret": {
+            "id": "[resourceId('Microsoft.Cdn/profiles/secrets', variables('profileName'), variables('secretName'))]"
+          }
+        }
+      },
+      "dependsOn": [
+        "[resourceId('Microsoft.Cdn/profiles', variables('profileName'))]",
+        "[resourceId('Microsoft.Cdn/profiles/secrets', variables('profileName'), variables('secretName'))]"
+      ]
+    },
+    {
+      "type": "Microsoft.Cdn/profiles/originGroups/origins",
+      "apiVersion": "2020-09-01",
+      "name": "[format('{0}/{1}/{2}', variables('profileName'), variables('originGroupName'), variables('originName'))]",
+      "properties": {
+        "hostName": "[parameters('originHostName')]",
+        "httpPort": 80,
+        "httpsPort": 443,
+        "originHostHeader": "[parameters('originHostName')]",
+        "priority": 1,
+        "weight": 1000
+      },
+      "dependsOn": [
+        "[resourceId('Microsoft.Cdn/profiles/originGroups', variables('profileName'), variables('originGroupName'))]",
+        "[resourceId('Microsoft.Cdn/profiles', variables('profileName'))]"
+      ]
+    },
+    {
+      "type": "Microsoft.Cdn/profiles/afdEndpoints/routes",
+      "apiVersion": "2020-09-01",
+      "name": "[format('{0}/{1}/{2}', variables('profileName'), parameters('endpointName'), variables('routeName'))]",
+      "properties": {
+        "customDomains": [
+          {
+            "id": "[resourceId('Microsoft.Cdn/profiles/customDomains', variables('profileName'), variables('customDomainResourceName'))]"
+          }
+        ],
+        "originGroup": {
+          "id": "[resourceId('Microsoft.Cdn/profiles/originGroups', variables('profileName'), variables('originGroupName'))]"
+        },
+        "supportedProtocols": [
+          "Http",
+          "Https"
+        ],
+        "patternsToMatch": [
+          "/*"
+        ],
+        "queryStringCachingBehavior": "IgnoreQueryString",
+        "forwardingProtocol": "HttpsOnly",
+        "linkToDefaultDomain": "Enabled",
+        "httpsRedirect": "Enabled"
+      },
+      "dependsOn": [
+        "[resourceId('Microsoft.Cdn/profiles/customDomains', variables('profileName'), variables('customDomainResourceName'))]",
+        "[resourceId('Microsoft.Cdn/profiles/afdEndpoints', variables('profileName'), parameters('endpointName'))]",
+        "[resourceId('Microsoft.Cdn/profiles/originGroups/origins', variables('profileName'), variables('originGroupName'), variables('originName'))]",
+        "[resourceId('Microsoft.Cdn/profiles/originGroups', variables('profileName'), variables('originGroupName'))]",
+        "[resourceId('Microsoft.Cdn/profiles', variables('profileName'))]"
+      ]
+    }
+  ],
+  "outputs": {
+    "customDomainValidationDnsTxtRecordName": {
+      "type": "string",
+      "value": "[format('_dnsauth.{0}', reference(resourceId('Microsoft.Cdn/profiles/customDomains', variables('profileName'), variables('customDomainResourceName'))).hostName)]"
+    },
+    "customDomainValidationDnsTxtRecordValue": {
+      "type": "string",
+      "value": "[reference(resourceId('Microsoft.Cdn/profiles/customDomains', variables('profileName'), variables('customDomainResourceName'))).validationProperties.validationToken]"
+    },
+    "customDomainValidationExpiry": {
+      "type": "string",
+      "value": "[reference(resourceId('Microsoft.Cdn/profiles/customDomains', variables('profileName'), variables('customDomainResourceName'))).validationProperties.expirationDate]"
+    },
+    "frontDoorEndpointHostName": {
+      "type": "string",
+      "value": "[reference(resourceId('Microsoft.Cdn/profiles/afdEndpoints', variables('profileName'), parameters('endpointName'))).hostName]"
+    }
+  }
+}
\ No newline at end of file
diff --git a/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/azuredeploy.parameters.json b/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/azuredeploy.parameters.json
new file mode 100644
index 0000000..8364381
--- /dev/null
+++ b/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/azuredeploy.parameters.json
@@ -0,0 +1,18 @@
+{
+    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
+    "contentVersion": "1.0.0.0",
+    "parameters": {
+        "customDomainName": {
+            "value": "GEN-FRONTDOOR-CUSTOM-HOSTNAME"
+        },
+        "certificateKeyVaultName": {
+            "value": "GEN-KEYVAULT-NAME"
+        },
+        "certificateKeyVaultSecretName": {
+            "value": "GEN-KEYVAULT-SSL-SECRET-NAME"
+        },
+        "originHostName": {
+            "value": "GEN-STATIC-WEBSITE-HOST-NAME"
+        }
+    }
+}
diff --git a/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/main.bicep b/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/main.bicep
new file mode 100644
index 0000000..e048ac4
--- /dev/null
+++ b/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/main.bicep
@@ -0,0 +1,157 @@
+@description('The name of the Front Door endpoint to create. This must be globally unique.')
+param endpointName string = 'afd-${uniqueString(resourceGroup().id)}'
+
+@description('The name of the SKU to use when creating the Front Door profile.')
+@allowed([
+  'Standard_AzureFrontDoor'
+  'Premium_AzureFrontDoor'
+])
+param skuName string = 'Standard_AzureFrontDoor'
+
+@description('The host name that should be used when connecting from Front Door to the origin.')
+param originHostName string
+
+@description('The custom domain name to associate with your Front Door endpoint.')
+param customDomainName string
+
+@description('The name of the resource group that contains the key vault with custom domain\'s certificate.')
+param certificateKeyVaultResourceGroupName string = resourceGroup().name
+
+@description('The name of the Key Vault that contains the custom domain\'s certificate.')
+param certificateKeyVaultName string
+
+@description('The name of the Key Vault secret that contains the custom domain\'s certificate.')
+param certificateKeyVaultSecretName string
+
+@description('The version of the Key Vault secret that contains the custom domain\'s certificate. Set the value to an empty string to use the latest version.')
+param certificateKeyVaultSecretVersion string = ''
+
+var profileName = 'MyFrontDoor'
+var originGroupName = 'MyOriginGroup'
+var originName = 'MyOrigin'
+var routeName = 'MyRoute'
+var secretName = 'MySecret'
+
+// Create a valid resource name for the custom domain. Resource names don't include periods.
+var customDomainResourceName = replace(customDomainName, '.', '-')
+
+resource profile 'Microsoft.Cdn/profiles@2020-09-01' = {
+  name: profileName
+  location: 'global'
+  sku: {
+    name: skuName
+  }
+}
+
+resource endpoint 'Microsoft.Cdn/profiles/afdEndpoints@2020-09-01' = {
+  name: endpointName
+  parent: profile
+  location: 'global'
+  properties: {
+    originResponseTimeoutSeconds: 240
+    enabledState: 'Enabled'
+  }
+}
+
+resource originGroup 'Microsoft.Cdn/profiles/originGroups@2020-09-01' = {
+  name: originGroupName
+  parent: profile
+  properties: {
+    loadBalancingSettings: {
+      sampleSize: 4
+      successfulSamplesRequired: 3
+    }
+    healthProbeSettings: {
+      probePath: '/'
+      probeRequestType: 'HEAD'
+      probeProtocol: 'Http'
+      probeIntervalInSeconds: 100
+    }
+  }
+}
+
+resource keyVault 'Microsoft.KeyVault/vaults@2021-06-01-preview' existing = {
+  scope: resourceGroup(certificateKeyVaultResourceGroupName)
+  name: certificateKeyVaultName
+
+  resource secret 'secrets' existing = {
+    name: certificateKeyVaultSecretName
+  }
+}
+
+resource secret 'Microsoft.Cdn/profiles/secrets@2020-09-01' = {
+  name: secretName
+  parent: profile
+  properties: {
+    parameters: {
+      type: 'CustomerCertificate'
+      useLatestVersion: (certificateKeyVaultSecretVersion == '')
+      secretVersion: certificateKeyVaultSecretVersion
+      secretSource: {
+        id: keyVault::secret.id
+      }
+    }
+  }
+}
+
+resource customDomain 'Microsoft.Cdn/profiles/customDomains@2020-09-01' = {
+  name: customDomainResourceName
+  parent: profile
+  properties: {
+    hostName: customDomainName
+    tlsSettings: {
+      certificateType: 'CustomerCertificate'
+      minimumTlsVersion: 'TLS12'
+      secret: {
+        id: secret.id
+      }
+    }
+  }
+}
+
+resource origin 'Microsoft.Cdn/profiles/originGroups/origins@2020-09-01' = {
+  name: originName
+  parent: originGroup
+  properties: {
+    hostName: originHostName
+    httpPort: 80
+    httpsPort: 443
+    originHostHeader: originHostName
+    priority: 1
+    weight: 1000
+  }
+}
+
+resource route 'Microsoft.Cdn/profiles/afdEndpoints/routes@2020-09-01' = {
+  name: routeName
+  parent: endpoint
+  dependsOn:[
+    origin // This explicit dependency is required to ensure that the origin group is not empty when the route is created.
+  ]
+  properties: {
+    customDomains: [
+      {
+        id: customDomain.id
+      }
+    ]
+    originGroup: {
+      id: originGroup.id
+    }
+    supportedProtocols: [
+      'Http'
+      'Https'
+    ]
+    patternsToMatch: [
+      '/*'
+    ]
+    queryStringCachingBehavior: 'IgnoreQueryString'
+    forwardingProtocol: 'HttpsOnly'
+    linkToDefaultDomain: 'Enabled'
+    httpsRedirect: 'Enabled'
+  }
+}
+
+output customDomainValidationDnsTxtRecordName string = '_dnsauth.${customDomain.properties.hostName}'
+output customDomainValidationDnsTxtRecordValue string = customDomain.properties.validationProperties.validationToken
+output customDomainValidationExpiry string = customDomain.properties.validationProperties.expirationDate
+output frontDoorEndpointHostName string = endpoint.properties.hostName
diff --git a/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/metadata.json b/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/metadata.json
new file mode 100644
index 0000000..0f10192
--- /dev/null
+++ b/quickstarts/microsoft.cdn/front-door-standard-premium-custom-domain-customer-certificate/metadata.json
@@ -0,0 +1,13 @@
+{
+  "$schema": "https://aka.ms/azure-quickstart-templates-metadata-schema#",
+  "type": "QuickStart",
+  "itemDisplayName": "Front Door Standard/Premium with domain and certificate",
+  "description": "This template creates a Front Door Standard/Premium including a custom domain and customer-managed certificate.",
+  "summary": "This template creates a Front Door Standard/Premium including a custom domain and customer-managed certificate.",
+  "githubUsername": "johndowns",
+  "docOwner": "johndowns",
+  "dateUpdated": "2022-03-03",
+  "environments": [
+    "AzureCloud"
+  ]
+}
\ No newline at end of file