从 Azure Pipeline 重复调用 Import-AzKeyVaultCertificate 时如何避免状态码冲突?

How to avoid the status code Conflict when repeatedly calling Import-AzKeyVaultCertificate from an Azure Pipeline?

我正在尝试建立一个管道,它将:

我用于生成自签名证书的 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:\CurrentUser\My -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

冲突错误代码在 Certificate Creation methods 中描述为:

When a KV certificate is created for the first time, an addressable key and secret is also created with the same name as that of the certificate. If the name is already in use, then the operation will fail with an http status code of 409 (conflict). The addressable key and secret get their attributes from the KV certificate attributes. The addressable key and secret created this way are marked as managed keys and secrets, whose lifetime is managed by Key Vault. Managed keys and secrets are read-only. Note: If a KV certificate expires or is disabled, the corresponding key and secret will become inoperable.

If this is the first operation to create a KV certificate then a policy is required. A policy can also be supplied with successive create operations to replace the policy resource. If a policy is not supplied, then the policy resource on the service is used to create a next version of KV certificate. Note that while a request to create a next version is in progress, the current KV certificate, and corresponding addressable key and secret, remain unchanged.

我的问题是我不明白启用重复调用我的 PowerShell 脚本的含义和操作方法。

我已经尝试从 KV 中手动删除证书,并且还在同一个 KV 中搜索具有相同名称的密钥和机密(因为文档告诉“还创建了一个可寻址的密钥和机密”)——但确实如此没用。

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

以下管道任务已经解决了我的问题-

  • 首先我从 KeyVault 中删除自签名证书(失败也可以)
  • 然后我从 KeyVault 中清除自签名证书(失败也可以)
  • 终于再次导入自签名证书

请注意清除命令使用 deletedcertificates id。

# Note: to generate a self-signed cert, follow the following steps:
# $SecurePassword = ConvertTo-SecureString -String 'password123' -AsPlainText -Force
# $NewCert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName 'myhost.westeurope.cloudapp.azure.com'
# Export-PfxCertificate -FilePath C:\Temp\my-self-signed-cert.pfx -Password $SecurePassword -Cert $NewCert
# $Bytes = [System.IO.File]::ReadAllBytes('C:\temp\my-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"