如何通过 ARM 模板在 Azure CDN 的 CustomDomain 中启用 HTTPS

Deb*_*osh 5 azure-cdn azure-resource-manager azure-devops

我已经通过 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 的整个创建。

有没有办法为 CustomDomain 彻底的 DevOps 启用 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

Run Code Online (Sandbox Code Playgroud)

在 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

Run Code Online (Sandbox Code Playgroud)

在 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
Run Code Online (Sandbox Code Playgroud)

Deb*_*osh 3

通过PowerShell脚本并调用Rest API实现自定义域的HTTPS启用。至少现在;我无法通过“ az cdn custom-domain enable-https ”进行操作,没有获得--custom-domain-https-parameters的正确示例。

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

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

我遵循的步骤 -

参考 - https://learn.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://learn.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!"
Run Code Online (Sandbox Code Playgroud)

在调用之前按照博客检查配置状态。