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