如何避免从 Azure 管道重复调用导入 AzKeyVault 证书时的状态代码冲突?



我正在尝试设置一个管道,它将:

  • 使用AzureResourceManagerTemplateDeployment@3任务部署密钥保管库"我的密钥保管库">
  • 运行 Powershell 脚本(如下所示(以在密钥保管库中创建自签名证书
  • 最后,通过使用AzureResourceManagerTemplateDeployment@3任务部署SF集群"my-cluster",并为节点到节点和客户端到节点的通信提供上述证书(稍后我计划引入2种不同的证书(。

用于生成自签名证书的 PowerShell 脚本在第一次调用时运行良好:

param(
[string] [Parameter(Mandatory=$true)] $Password,
[string] [Parameter(Mandatory=$true)] $CertDnsName,
[string] [Parameter(Mandatory=$true)] $KeyVaultName,
[string] [Parameter(Mandatory=$true)] $CertName
)
$SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
$CertFileFullPath = $(Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Definition) "$CertDnsName.pfx")
$NewCert = New-SelfSignedCertificate -CertStoreLocation Cert:CurrentUserMy -DnsName $CertDnsName 
Export-PfxCertificate -FilePath $CertFileFullPath -Password $SecurePassword -Cert $NewCert
Import-AzKeyVaultCertificate -VaultName $KeyVaultName -Name $CertName -FilePath $CertFileFullPath -Password $SecurePassword

然而,当我反复调用它时——

New-ServiceFabricClusterCertificate.ps1 -Password "blah" -CertDnsName "my-hostname" -KeyVaultName "my-keyvault" -CertName "my-cluster-cert"

然后我得到错误:

Import-AzKeyVaultCertificate : Operation returned an invalid status code 'Conflict'
+ ... NewSecret = Import-AzKeyVaultCertificate -VaultName $KeyVaultName -Na ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : CloseError: (:) [Import-AzKeyVaultCertificate], KeyVaultErrorException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.KeyVault.ImportAzureKeyVaultCertificate

冲突错误代码在证书创建方法中描述为:

首次创建KV证书时,还会创建与证书同名的可寻址密钥和密钥。如果该名称已在使用中,则操作将失败,http 状态代码为 409(冲突(。可寻址密钥和机密从 KV 证书属性中获取其属性。以这种方式创建的可寻址密钥和机密标记为托管密钥和机密,其生存期由 Key Vault 管理。托管密钥和机密是只读的。注意:如果 KV 证书过期或被禁用,则相应的密钥和密钥将变得无法运行。

如果这是创建 KV 证书的第一个操作,则需要策略。还可以为策略提供连续的创建操作来替换策略资源。如果未提供策略,则服务上的策略资源将用于创建下一版本的 KV 证书。请注意,当创建下一个版本的请求正在进行时,当前 KV 证书以及相应的可寻址密钥和机密保持不变。

我的问题是我不明白它的含义以及如何启用对我的PowerShell脚本的重复调用。

我尝试从 KV 手动删除证书,并在具有相同名称的同一 KV 中搜索密钥和机密(因为文档告诉"还创建了一个可寻址的密钥和机密"( - 但这没有帮助。

现在,每当我运行脚本时,我都会收到冲突错误!

以下管道任务为我解决了这个问题——

  • 首先,我从密钥保管库中删除自签名证书(失败是可以的(
  • 然后我从密钥保管库中清除自签名证书(失败是可以的(
  • 最后我再次导入自签名证书

请注意,清除命令使用deletedcertificatesid。

# Note: to generate a self-signed cert, follow the following steps:
# $SecurePassword = ConvertTo-SecureString -String 'password123' -AsPlainText -Force
# $NewCert = New-SelfSignedCertificate -CertStoreLocation Cert:LocalMachineMy -DnsName 'myhost.westeurope.cloudapp.azure.com'
# Export-PfxCertificate -FilePath C:Tempmy-self-signed-cert.pfx -Password $SecurePassword -Cert $NewCert
# $Bytes = [System.IO.File]::ReadAllBytes('C:tempmy-self-signed-cert.pfx')
# $Base64 = [System.Convert]::ToBase64String($Bytes)
# After that please copy-paste the Base64 content into the task below
# purge the self-signed cert from the Keyvault to avoid conflict; ignore failures
- task: AzureCLI@2
inputs:
azureSubscription: '${{ parameters.mysub }}'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
powerShellErrorActionPreference: 'silentlyContinue'
inlineScript: |
az keyvault certificate delete --vault-name mykeyvault --id 'https://mykeyvault.vault.azure.net/certificates/my-self-signed-cert'
az keyvault certificate purge --vault-name mykeyvault --id 'https://mykeyvault.vault.azure.net/deletedcertificates/my-self-signed-cert'
# import the self-signed certificate into the Keyvault
- task: AzurePowerShell@5
inputs:
azureSubscription: '${{ parameters.mysub }}'
ScriptType: 'InlineScript'
azurePowerShellVersion: '3.1.0'
Inline: |
$Pwd = ConvertTo-SecureString -String 'password123' -Force -AsPlainText
$Base64 = 'MIIK....3000_chars_here_base64_encoded_...U1ICAgfQ=='
$Cert = Import-AzKeyVaultCertificate -VaultName mykeyvault -Name my-self-signed-cert -CertificateString $Base64 -Password $Pwd
echo "##vso[task.setvariable variable=Thumbprint;isOutput=true]$Cert.Thumbprint"

最新更新