从 ARM 模板中的 Azure 密钥保管库获取最新版本的证书

Get the latest version of a certificate from an Azure key vault in an ARM template

正在创建需要安装位于 Azure 密钥保管库内的 SSL 证书的 ARM 模板。如果我用指纹指定证书,它工作正常:

https://contoso.vault.azure.net/secrets/web01-test-contoso-com/968bf207451149d3aceb390065af9d3a

但是由于证书是在滴答作响的时钟上,这硬编码了一个可能会过时的依赖项到 ARM 模板中。我宁愿只指定最新版本(就像它在门户中显示的那样)。但是,我没有找到任何说明如何执行此操作的文档,甚至没有提及是否可能。

我运行几个实验使用:

https://contoso.vault.azure.net/secrets/web01-test-contoso-com

https://contoso.vault.azure.net/secrets/web01-test-contoso-com/latest

但在这两种情况下,我都收到了相同的错误消息:

message '{
   "error": {
     "code": "InvalidParameter",
     "message": "https://contoso.vault.azure.net/secrets/web01-test-contoso-com/latest is 
 not a valid versioned Key Vault Secret URL. It should be in the format 
 https://<vaultEndpoint>/secrets/<secretName>/<secretVersion>.",
     "target": "certificateUrl"
   }
}'

所以我的问题是:如何以获取最新版本的方式引用证书?

为清楚起见,我在 VM 的 ARM 模板的 secrets 部分中使用 URL,如下所示,它从 Azure 密钥保管库获取证书并将其安装到 Windows证书存储。

"secrets": [
    {
      "sourceVault": {
        "id": "[resourceId(parameters('keyVaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('keyVaultName'))]"
      },
      "vaultCertificates": [
        {
          "certificateUrl": "https://contoso.vault.azure.net/secrets/web01-test-contoso-com/latest",
          "certificateStore": "My"
        }
      ]
    }
]

NOTE: I would find it odd that you can specify the latest version of an OS to install, but you cannot specify to install the latest version of a certificate.

没有 direct\easy 方法可以做到这一点。 Key Vault 对 arm 模板不太友好。

正如 juunas 所建议的那样,您可以编写脚本或使用自定义脚本扩展来使用托管服务标识直接从密钥保管库中提取数据。

根据@4c74356b41 的回答,我在 python 脚本中自己完成了。

      data = json.loads(kv_auth_response.content)
      #
      ## Lets find youngest vesrion of certificate
      #
      if len(data['value']) > 0:
         for x in range(len(data['value'])):
             if x == 0:
                youngest = data['value'][x]['attributes']['exp']
                cert_url = data['value'][x]
             if data['value'][x]['attributes']['exp'] > youngest:
                youngest = data['value'][x]['attributes']['exp']
                cert_url = data['value'][x]
         arry = cert_url['id'].split('/')
...
         cert_version = arry[len(arry)-1]

在循环的第一步,过期日期的值被分配给 "youngest" 变量。在接下来的步骤中,脚本将过期日期与其进行比较,并在满足条件时进行分配。 循环脚本用 "yougests" cert_url 拆分后,将数组的最后一部分分配给 "cert_version" 变量。

您可以在我的自定义域 BYOC 脚本中看到此问题的完整视图。 Link: https://github.com/przemika/azure-byoc-for-custom-domain/blob/master/start-byoc.py

有可能,与公认的答案相反。 像这样使用 secret 的资源 id 定义变量,例如:

"mySecretResourceId": "[concat(resourceGroup().id,'/providers/Microsoft.KeyVault/vaults/', variables('keyVaultName'), '/secrets/', 'my-secret-name')]"

然后您可以在您的模板中使用它,如下所示:

"certificateUrl": "[reference(variables('mySecretResourceId'), '2018-02-14').secretUriWithVersion]"