Azure Keyvault добавить функцию MSI через ARM

Я думаю, что Managed Service Identity - это отличная концепция, и я люблю keyvault. Тем не мение:

Когда я использую сценарий с использованием инкрементного развертывания группы ресурсов:

Образец доработан для краткости

{
      "type": "Microsoft.KeyVault/vaults",
      "name": "[parameters('keyvaultName')]",
      "apiVersion": "2015-06-01",
      "properties": {            
        "accessPolicies": [
          {
            "objectId": "[reference(parameters('functionAppName'), '2016-08-01', 'Full').identity.principalId]",
            "permissions": {
              "keys": [],
              "secrets": [
                "Get"
              ]
            }
          }
        ]
      },
      "dependsOn": [
        "[resourceId('Microsoft.Web/sites', parameters('functionAppName'))]"
      ]
    },
    {
      "apiVersion": "2016-08-01",
      "type": "Microsoft.Web/sites",
      "name": "[parameters('functionAppName')]",
      "kind": "functionapp",
      "identity": {
        "type": "SystemAssigned"
      },
    }

Он успешно разворачивается и добавляет MSI в keyvault, но -

Сносит уже назначенные политики доступа. Возможно ли для руки сохранить accessPolicies и только добавить / обновить политики, которые соответствуют?

Без этого невозможно полностью выполнить сценарий развертывания с помощью MSI, а также назначить принципала для keyvault.

Я что-то пропустил?

2 ответа

Как автор поста в блоге, я выложу детали по модам:

При развертывании ресурса типа Microsoft.KeyVault/vaults/accessPolicies с именем "add" он будет объединен с вашими изменениями. Этот специальный дочерний тип ресурса был создан, чтобы разрешить сценарии идентификации управляемых служб, в которых вы не знаете идентификатор виртуальной машины до тех пор, пока виртуальная машина не будет развернута, и вы хотите предоставить этому идентификатору доступ к хранилищу во время развертывания.

Инкрементное развертывание может использоваться вместе с этим json для достижения цели:

{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "vaultName": {
            "type": "string"
        }
    },
    "resources": [
        {
            "type": "Microsoft.KeyVault/vaults/accessPolicies",
            "name": "[concat(parameters('vaultName'), '/add')]",
            "apiVersion": "2016-10-01",
            "properties": {
                "accessPolicies": [
                    {
                        "tenantId": "dfe47ca8-acfc-4539-9519-7d195a9e79e4",
                        "objectId": "5abe9358-10ae-4195-ba23-d34111430329",
                        "permissions": {
                            "keys": ["all"],
                            "secrets": ["all"],
                            "certificates": ["all"],
                            "storage": ["all"]
                        }
                    }
                ]
            }
        }
    ],
    "outputs": {
    }
}

Проблема с ответом, получившим наибольшее количество голосов, заключается в том, что он полностью удаляет хранилище ключей из шаблона ARM, а это означает, что создание хранилища ключей становится ручным процессом в новых средах.

ARM не позволяет повторно развернуть хранилище ключей без очистки существующих политик доступа. В свойство является обязательным (кроме случаев восстановления удаленного хранилища), поэтому его пропуск приведет к ошибке. Установив его на очистит все существующие политики. на исправление этой проблемы в ЗапросMicrosoft отправляется с 2018 года, и в настоящее время он получил 152 голоса.

Лучший способ, который я нашел для решения этой проблемы, - это сделать хранилище ключей условно развернутым, только если оно еще не существует, и определить политики доступа с помощью отдельного дочерний ресурс. Это приводит к добавлению или обновлению указанных политик с сохранением любых других существующих политик. Я проверяю, существует ли уже хранилище ключей, передавая список существующих имен ресурсов в шаблон 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'

В шаблоне 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.
            ]
          }
        }
      ]
    }
  ]
}
Другие вопросы по тегам