我认为管理服务标识是一个很棒的概念,我喜欢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,但是 -
它吹走了已经分配的访问策略。 arm是否可以保留accessPolicies并仅添加/更新匹配的策略?
如果没有这个,就不可能用MSI完全编写部署脚本并将主体分配给keyvault ..
我错过了什么吗?
答案 0 :(得分:5)
作为blog post的作者,我会根据mod发布详细信息:
当您部署名为“add”的Microsoft.KeyVault / vaults / accessPolicies类型的资源时,它将合并您的更改。创建此特殊子资源类型是为了允许在部署VM之前您不知道VM身份的托管服务标识方案,并且您希望在部署期间授予该标识对Vault的访问权限。
可以与此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": {
}
}
答案 1 :(得分:0)
highest-voted answer 的问题在于它从 ARM 模板中完全删除了密钥保管库,这意味着密钥保管库的创建成为新环境中的手动过程。
ARM 不允许在不清除其现有访问策略的情况下重新部署密钥保管库。 accessPolicies
属性为 required(恢复已删除的保管库时除外),因此省略它会导致错误。将其设置为 []
将清除所有现有策略。自 2018 年以来,一直有 Microsoft Feedback request 解决此问题,目前有 152 票。
我发现的解决此问题的最佳方法是仅在 Key Vault 不存在时有条件地部署它,并且通过单独的 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'
在 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.
]
}
}
]
}
]
}