I have created Azure CDN through ARM template from Azure DevOps by CI/CD, followed the below references -
https://github.com/Azure/azure-quickstart-templates/tree/master/201-cdn-with-storage-account
https://docs.microsoft.com/en-us/azure/templates/microsoft.cdn/2019-04-15/profiles/endpoints/customdomains
Azure CDN created and mapped the Custom Domain with Endpoint. But not sure how do I enable HTTPS (My Own certificate available in KeyVault) in custom domain through ARM (from Azure DevOps) template, options are not available in MS template reference.
Want to automate the whole creation of Azure CDN.
Is there a way to enable HTTPS for CustomDomain thorough DevOps?
Here is my script (not the final) -
#Enable Https in Custom Domain - Azure CDN
$cdnProfileName ='debtestcdnprofile'
$cdnEndpointName = 'debtestcdnendpoint'
$cdnCustomDomainName = 'mysubdomain-mydomain-com' # testing
$keyVaultName = 'debkeyvault'
$certificateName = 'debasiscert'
$apiVersion = '2019-04-15'
$secretVersion = 'XXXXXXXXXXX'
$secretName = 'debasiscert'
$keyVaultResourceGroupName = 'rsgStgCDN'
$cdnProfile = Get-AzCdnProfile -ProfileName $cdnProfileName;
$resourceGroup = Get-AzResourceGroup -Name $cdnProfile.ResourceGroupName;
$resourceGroupName = $resourceGroup.ResourceGroupName;
$context = Get-AzContext;
$subscriptionId = $context.Subscription.Id;
$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile;
$profileClient = New-Object Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient($azProfile);
$token = $profileClient.AcquireAccessToken($context.Subscription.TenantId);
$accessToken = $token.AccessToken;
write-verbose -verbose "[INF] Access token : $($accessToken)"
$StateUri = "https://management.azure.com/subscriptions/$($subscriptionId)/resourcegroups/$($resourceGroupName)/providers/Microsoft.Cdn/profiles/$($cdnProfileName)/endpoints/$($cdnEndpointName)/customdomains/$($cdnCustomDomainName)?api-version=$($apiVersion)"
$ProvisionUri = "https://management.azure.com/subscriptions/$($subscriptionId)/resourcegroups/$($resourceGroupName)/providers/Microsoft.Cdn/profiles/$($cdnProfileName)/endpoints/$($cdnEndpointName)/customdomains/$($cdnCustomDomainName)/enableCustomHttps?api-version=$($apiVersion)"
$body = $ExecutionContext.InvokeCommand.ExpandString('{"certificateSource":"AzureKeyVault","protocolType":"ServerNameIndication","certificateSourceParameters":{"@odata.type":"#Microsoft.Azure.Cdn.Models.KeyVaultCertificateSourceParameters","subscriptionId":"$subscriptionId","resourceGroupName":"$keyVaultResourceGroupName","vaultName":"$keyVaultName","SecretName":"$secretName","SecretVersion":"$secretVersion","updateRule":"NoAction","deleteRule":"NoAction"}}')
$headers = @{ }
$headers.Add('Authorization', "Bearer $accessToken")
$headers.Add('Content-Type', 'application/json')
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
$state = (Invoke-RestMethod -Method GET -Uri $StateUri -Headers $headers).properties.customHttpsProvisioningState
Throwing same issue in CI/CD as well as while executing through PowerShell
Issue -
Invoke-RestMethod : {
"error": {
"code": "NotFound",
"message": "The resource cannot be found."
}
At line:51 char:11
+ $state = (Invoke-RestMethod -Method GET -Uri $StateUri -Headers $hea ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], We
bException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Executing the "Get-AzCdnCustomDomain" command in PowerShell also throwing bad request -
PS C:\WINDOWS\system32> Get-AzCdnCustomDomain -ResourceGroupName 'XXXXX' -ProfileName 'XXXXX' -EndpointName 'XXXXX' -CustomDomainNa
me 'subdomain.domain.com'
Get-AzCdnCustomDomain : Operation returned an invalid status code 'BadRequest'
At line:1 char:1
+ Get-AzCdnCustomDomain -ResourceGroupName 'XXXXX' -Prof ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Get-AzCdnCustomDomain], ErrorResponseException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Cdn.CustomDomain.GetAzureRmCdnCustomDomain
Enable HTTPS in CustomDomain in Azure CDN through ARM Template
If you want to achieve this by using ARM template, unfortunately, it haven't supported to add HTTPS
for endpoint in the ARM template until now. So, even using Azure Devops, it also could not be make true by using ARM template.
But in the pipeline of VSTS, you can using a short Powershell script by calling below API to enable the HTTPS:
POST https://management.azure.com/subscriptions/{subscription id}/resourcegroups/{resourceGroup name}/providers/Microsoft.Cdn/profiles/{Cdnprofile name)/endpoints/{cdnEndpointName}/customdomains/customDomain/enableCustomHttps?api-version=2018-04-02"
As you mentioned, you store the certificate in Key Vault, you need specify the key vault as certificateSource
in this request body:
{
"certificateSource": "AzureKeyVault",
"protocolType": "ServerNameIndication",
"certificateSourceParameters": {
"@odata.type": "#Microsoft.Azure.Cdn.Models.KeyVaultCertificateSourceParameters",
"subscriptionId": "$subId",
"resourceGroupName": "$resourceGroupKv",
"vaultName": "$kvName",
"SecretName": "$secretName",
"SecretVersion": "$version",
"updateRule": "NoAction",
"deleteRule": "NoAction"
}
}
For details, please check this doc to configure your request body based on your actual need.
Also, there has someone describe the detailed steps and scripts for how to using Powershell to call this API. You can refer to that blog.
Want to automate the whole creation of Azure CDN.
Now, you should have got how to enable HTTPS. So the issue is how to create the the completed Azure CDN automatically in VSTS.
Step1: Add a agent job.
Step2: Add a first task Azure resource group deployment
Apply the ARM template by using Azure resource group deployment task in Build/Release pipeline. This task is available both in build and release pipeline.
Step3: Add a second task Powershell
and input the above enable HTTPS powershell script into inline type.
After configure them, run this pipeline, then it can achieve automate the whole creation of Azure CDN.
You can apply these steps in CI or CD, anyone is available in VSTS.
Enabling HTTPS of the custom domain achieved through PowerShell script and invoking the Rest API. At least now; I am unable to do through "az cdn custom-domain enable-https", did not get proper sample for --custom-domain-https-parameters.
Due to bad mistake always I'm receiving HTTP status 400 from Rest API. Reason is I am passing domain name (host name) instead of friendly name mapping to the endpoint. (e.g. - my domain name or host name is : mysubdomain.domainname.com and friendly name is MyDevDomain; then Rest API is expecting MyDevDomain)
We can follow @Merlin Liang - MSFT steps to automate the process.
Steps I followed -
ref - https://docs.microsoft.com/en-us/azure/cdn/cdn-custom-ssl?tabs=option-2-enable-https-with-your-own-certificate#ssl-certificates
https://www.nlymbery.com.au/posts/azure-cdn-automate-provisioning-custom-certificate/
https://gist.github.com/HQJaTu/c5695626ba51c6194845fa60913e911b
$cdnProfile = Get-AzCdnProfile -ProfileName $cdnProfileName;
$resourceGroup = Get-AzResourceGroup -Name $cdnProfile.ResourceGroupName;
$resourceGroupName = $resourceGroup.ResourceGroupName;
# Get Access Token to invoke in Rest API
$context = Get-AzContext;
$subscriptionId = $context.Subscription.Id;
$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile;
if (-not $azProfile.Accounts.Count) {
Write-Error "Error occured!"
Exit 1
}
$profileClient = New-Object Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient($azProfile);
$token = $profileClient.AcquireAccessToken($context.Subscription.TenantId) ;
$accessToken = $token.AccessToken;
if (-not $accessToken) {
Write-Error "Error occured!";
Exit 1
}
# Update certificate values
# ref - https://docs.microsoft.com/en-us/rest/api/cdn/customdomains/enablecustomhttps
$ProvisionUri = "https://management.azure.com/subscriptions/$($subscriptionId)/resourcegroups/$($resourceGroupName)/providers/Microsoft.Cdn/profiles/$($cdnProfileName)/endpoints/$($cdnEndpointName)/customdomains/$($cdnCustomDomainName)/enableCustomHttps?api-version=$($apiVersion)"
$body = $ExecutionContext.InvokeCommand.ExpandString('{"certificateSource":"AzureKeyVault","protocolType":"ServerNameIndication","certificateSourceParameters":{"@odata.type":"#Microsoft.Azure.Cdn.Models.KeyVaultCertificateSourceParameters","subscriptionId":"$subscriptionId","resourceGroupName":"$keyVaultResourceGroupName","vaultName":"$keyVaultName","SecretName":"$secretName","SecretVersion":"$secretVersion","updateRule":"NoAction","deleteRule":"NoAction"}}')
$headers = @{ }
$headers.Add('Authorization', "Bearer $accessToken")
$headers.Add('Content-Type', 'application/json')
write-verbose -verbose "[INF] Provision Uri: $($ProvisionUri)"
write-verbose -verbose "[INF] Headers: $($headers)"
write-verbose -verbose "[INF] Body: $($body)"
Write-Verbose -Verbose "Applying custom certificate to $($cdnProfileName):$($cdnEndpointName)"
Invoke-RestMethod -Method Post -Uri $ProvisionUri -Headers $headers -Body $body
write-verbose -verbose "[INF] Script executed successfully!"
before invoking check the provisioning state as per the blog.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With