Azure ARM 模板 Keyvault 资源不断删除其他访问策略

And*_*yen 5 deployment azure azure-keyvault

我创建了一个 ARM 模板来部署一个 Azure WebApp,该应用程序使用托管服务身份验证和 KeyVault 来获取机密。因此,ARM 模板创建 WebApp 资源并启用 MSI,还创建 KeyVault 资源并将 WebApptenantid 和 objectid 添加到 accessPolicies,但是,ARM 模板还会从我的 Keyvault 中删除所有其他现有访问策略。

有没有办法对访问策略进行增量部署,这样我就不必在部署后将用户添加回 KeyVault 访问策略?

{
  "type": "Microsoft.KeyVault/vaults",
  "name": "[parameters('ICMODSKeyVaultName')]",
  "apiVersion": "2016-10-01",
  "location": "[resourceGroup().location]",
  "properties": {
    "sku": {
      "family": "A",
      "name": "standard"
    },
    "tenantId": "[reference(variables('identityResourceId'), '2015-08-31-PREVIEW').tenantId]",
    "accessPolicies": [
      {
        "tenantId": "[reference(variables('identityResourceId'), '2015-08-31-PREVIEW').tenantId]",
        "objectId": "[reference(variables('identityResourceId'), '2015-08-31-PREVIEW').principalId]",
        "permissions": {
          "secrets": [
            "get"
          ]
        }
      }
    ],
    "enabledForDeployment": true,
    "enabledForTemplateDeployment":  true
  },
  "dependsOn": [
    "[concat('Microsoft.Web/sites/', parameters('AppName'))]"
  ]
}
Run Code Online (Sandbox Code Playgroud)

Dou*_*las 5

已接受答案的问题在于,它从 ARM 模板中完全删除了密钥保管库,这意味着密钥保管库的创建在新环境中变成了手动过程。

ARM 不允许在未清除现有访问策略的情况下重新部署密钥保管库。该accessPolicies属性是必需的(恢复已删除的保管库时除外),因此省略它会导致错误。将其设置为[]将清除所有现有策略。自 2018 年以来,一直有Microsoft 反馈请求修复此问题,目前已获得 152 票。

我发现解决此问题的最佳方法是仅在密钥保管库尚不存在时才进行有条件部署,通过单独的子资源定义访问策略add。这会导致添加或更新指定的策略,同时保留任何其他现有策略。我通过将现有资源名称列表传递到 ARM 模板来检查密钥保管库是否已存在。

在 Azure 管道中:

- task: AzurePowerShell@5
  displayName: 'Get existing resource names'
  inputs:
    azureSubscription: '$(armServiceConnection)'
    azurePowerShellVersion: 'LatestVersion'
    ScriptType: 'InlineScript'
    Inline: |      
      $resourceNames = (Get-AzResource -ResourceGroupName $(resourceGroupName)).Name | ConvertTo-Json -Compress
      Write-Output "##vso[task.setvariable variable=existingResourceNames]$resourceNames"
    azurePowerShellVersion: 'LatestVersion'

- task: AzureResourceManagerTemplateDeployment@3
  name: DeployResourcesTemplate
  displayName: 'Deploy resources through ARM template
  inputs:
    deploymentScope: 'Resource Group'
    action: 'Create Or Update Resource Group'
    # ...
    overrideParameters: >-
      -existingResourceNames $(existingResourceNames)
      # ...
    deploymentMode: 'Incremental'
Run Code Online (Sandbox Code Playgroud)

在ARM模板中:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",

  "parameters": {
    "keyVaultName": {
      "type": "string"
    },
    "existingResourceNames": {
      "type": "array",
      "defaultValue": []
    }
  },

  "resources": [
    {
      "type": "Microsoft.KeyVault/vaults",
      "apiVersion": "2016-10-01",
      "name": "[parameters('keyVaultName')]",
      "location": "[resourceGroup().location]",
      // Only deploy the key vault if it does not already exist.
      // Conditional deployment doesn't cascade to child resources, which can be deployed even when their parent isn't.
      "condition": "[not(contains(parameters('existingResourceNames'), parameters('keyVaultName')))]",
      "properties": {
        "sku": {
          "family": "A",
          "name": "Standard"
        },
        "tenantId": "[subscription().tenantId]",
        "enabledForDeployment": false,
        "enabledForDiskEncryption": false,
        "enabledForTemplateDeployment": true,
        "enableSoftDelete": true,
        "accessPolicies": []
      },
      "resources": [
        {
          "type": "accessPolicies",
          "apiVersion": "2016-10-01",
          "name": "add",
          "location": "[resourceGroup().location]",
          "dependsOn": [
            "[parameters('keyVaultName')]"
          ],
          "properties": {
            "accessPolicies": [
              // Specify your access policies here.
              // List does not need to be exhaustive; other existing access policies are preserved.
            ]
          }
        }
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)


4c7*_*b41 2

这是您应该得到的行为,因为 ARM 模板是幂等的。如果您将访问策略创建为单独的资源,您将能够更改此行为:

{
  "name": "vaultName/policyName",
  "location": xxx,
  "api-version": "2016-10-01",
  "type": "Microsoft.KeyVault/vaults/accessPolicies",
  "properties": {
    "accessPolicies": [
      {
        "tenantId": "00000000-0000-0000-0000-000000000000",
        "objectId": "00000000-0000-0000-0000-000000000000",
        "permissions": {
          "keys": [
            "encrypt"
          ],
          "secrets": [
            "get"
          ],
          "certificates": [
            "get"
          ]
        }
      }
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

请记住,这是一个粗略的草图,它可能行不通,但您可以相当轻松地使其工作。这是为了说明这个想法。

参考:https://learn.microsoft.com/en-us/rest/api/keyvault/vaults/updateaccesspolicy

  • 如果您在创建 Web 应用程序等时动态添加托管身份,这将无济于事。 keyvault 无法重新部署。您将失去所有访问策略。 (2认同)