如何通过 ARM 模板在 Azure CDN 中的自定义域上启用 HTTPS

How do I enable HTTPS in CustomDomain in Azure CDN through ARM Template

我已经通过 CI/CD 从 Azure DevOps 的 ARM 模板创建了 Azure CDN,遵循以下参考 -

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 使用端点创建并映射了自定义域。 但不确定如何通过 ARM(来自 Azure DevOps)模板在自定义域中启用 HTTPS(我自己的证书在 KeyVault 中可用),选项在 MS 模板参考中不可用。

想要自动化整个 Azure CDN 的创建。

有没有办法通过 DevOps 为 CustomDomain 启用 HTTPS?

这是我的脚本(不是最终的)-

#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

在 CI/CD 以及通过 PowerShell

执行时抛出相同的问题

问题 -

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

在 PowerShell 中执行 "Get-AzCdnCustomDomain" 命令也会抛出错误请求 -

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

如果你想通过ARM模板来实现,不幸的是,目前还不支持在ARM模板中为端点添加HTTPS。因此,即使使用 Azure Devops,它也可以 not 通过使用 ARM 模板 实现

但是在 VSTS 的管道中,您可以使用简短的 Powershell 脚本通过调用下面的 API 来启用 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" 

如您所述,您将证书存储在 Key Vault 中,您需要在此 request body:

中将密钥保管库指定为 certificateSource
{
  "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"
  }
}

有关详细信息,请查看此doc以根据您的实际需要配置您的请求正文。

另外,有人描述了如何使用Powershell调用这个的详细步骤和脚本API。你可以参考那个blog.


Want to automate the whole creation of Azure CDN.

现在,您应该了解了如何启用 HTTPS。所以问题是如何在VSTS中自动创建完整的Azure CDN。

步骤 1:添加代理作业。

Step2: 添加第一个任务Azure resource group deployment

通过在 Build/Release 管道中使用 Azure resource group deployment task 来应用 ARM 模板。此任务在构建和发布管道中均可用。

Step3: 添加第二个任务Powershell并将上面的enable HTTPS powershell脚本输入inline type.

配置好后,运行这个管道,就可以实现整个Azure CDN创建的自动化。

您可以在 CI 或 CD 中应用这些步骤,任何人都可以在 VSTS 中使用。

启用通过 PowerShell 脚本实现的自定义域的 HTTPS 并调用 Rest API. At least now; I am unable to do through "az cdn custom-domain enable-https",未获得 --custom-domain-https-parameters 的正确示例.

由于严重错误,我总是从 Rest API 收到 HTTP 状态 400。原因是我将域名(主机名)而不是友好名称映射传递到端点。 (例如 - 我的域名或主机名是:mysubdomain.domainname.com,友好名称是 MyDevDomain;然后 Rest API 期待 MyDevDomain)

我们可以按照@Merlin Liang - MSFT 的步骤来自动化该过程。

我遵循的步骤 -

ref - https://docs.microsoft.com/en-us/azure/cdn/cdn-custom-ssl?tabs=option-2-enable-https-with-your-own-certificate#ssl-certificates

  1. 在 Azure Active Directory 中注册 Azure CDN。
  2. 授予 Azure CDN 访问密钥保管库的权限。
  3. PowerShell 脚本 -

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!"

在调用之前根据博客检查配置状态。