azure-devops - 如何创建利用 Key Vault 的幂等、可重新部署的 ARM 模板?循环依赖存在问题

标签 azure-devops azure-resource-manager azure-keyvault azure-managed-identity infrastructure-as-code

我正在尝试在我的资源中加入一些额外的安全功能,例如使用客户管理的 key 进行加密。对于服务总线,这要求服务总线创建托管标识并授予对 Key Vault 的访问权限。但是,直到服务总线存在之后,托管身份才会被知晓。

在我的 ARM 模板中,我需要在不加密的情况下初始化服务总线,以获得托管身份,授予该身份对 key 保管库的访问权限,然后使用加密更新服务总线。然而,这个部署过程是不可重复的。在后续重新部署中,它将失败,因为加密一旦被授予就无法从服务总线中删除。即使它确实有效,我也会执行不必​​要的步骤来删除加密并将其添加回每个部署中。似乎描述资源预期最终状态的 IAC 模板不能用于维护和引导新环境。

API 管理也存在同样的问题,我想添加自定义域,但它们需要 Key Vault 访问权限。这意味着当重复初始化步骤时,我无法在不删除自定义域的情况下重新部署我的 ARM 模板(或者为“初始化”与“实际部署”保留一组单独的模板。

有没有更好的解决方案?我研究了用户分配的身份,这似乎可以解决问题,但 ARM 模板不支持它们。我检查了是否有办法通过检查资源是否已存在来使“init”步骤成为有条件的,并且 ARM 模板也不支持这一点。

最佳答案

如果您想维护单个ARM模板,可以使用nested deployments定义资源,然后再次引用它来更新它。

在以下示例中,我使用系统分配的托管标识、Key Vault 和 RSA key 创建服务总线。在依赖于生成的 key 的同一 ARM 模板内的嵌套部署中,我随后更新服务总线以启用加密。全部位于同一模板中的一个优点是 resourceIdreference 可以使用缩写语法(即仅资源名称)。

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "name": {
            "type": "string",
            "defaultValue": "[resourceGroup().name]"
        },
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]"
        },
        "tenantId": {
            "type": "string",
            "defaultValue": "[subscription().tenantId]"
        }
    },
    "variables": {
        "kv_name": "[concat(parameters('name'), 'kv')]",
        "kv_version": "2019-09-01",
        "sb_name": "[concat(parameters('name'), 'sb')]",
        "sb_version": "2018-01-01-preview",
        "sb_keyname": "sbkey"
    },
    "resources": [
        {
            "type": "Microsoft.ServiceBus/namespaces",
            "apiVersion": "[variables('sb_version')]",
            "name": "[variables('sb_name')]",
            "location": "[parameters('location')]",
            "sku": {
                "name": "Premium",
                "tier": "Premium",
                "capacity": 1
            },
            "identity": {
                "type": "SystemAssigned"
            },
            "properties": {
                "zoneRedundant": false
            }
        },
        {
            "type": "Microsoft.KeyVault/vaults",
            "apiVersion": "[variables('kv_version')]",
            "name": "[variables('kv_name')]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[variables('sb_name')]"
            ],
            "properties": {
                "sku": {
                    "family": "A",
                    "name": "Standard"
                },
                "tenantId": "[parameters('tenantId')]",
                "accessPolicies": [
                    {
                        "tenantId": "[reference(variables('sb_name'), variables('sb_version'), 'Full').identity.tenantId]",
                        "objectId": "[reference(variables('sb_name'), variables('sb_version'), 'Full').identity.principalId]",
                        "permissions": {
                            "keys": [
                                "get",
                                "wrapKey",
                                "unwrapKey"
                            ]
                        }
                    }
                ],
                // Both must be enabled to encrypt Service Bus at rest.
                "enableSoftDelete": true,
                "enablePurgeProtection": true
            }
        },
        {
            "type": "Microsoft.KeyVault/vaults/keys",
            "apiVersion": "[variables('kv_version')]",
            "name": "[concat(variables('kv_name'), '/', variables('sb_keyname'))]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[variables('kv_name')]"
            ],
            "properties": {
                "kty": "RSA",
                "keySize": 2048,
                "keyOps": [
                    "wrapKey",
                    "unwrapKey"
                ],
                "attributes": {
                    "enabled": true
                }
            }
        },
        {
            "type": "Microsoft.Resources/deployments",
            "apiVersion": "2020-10-01",
            "name": "sb_deployment",
            "dependsOn": [
                "[resourceId('Microsoft.KeyVault/vaults/keys', variables('kv_name'), variables('sb_keyname'))]"
            ],
            "properties": {
                "mode": "Incremental",
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "resources": [
                        {
                            "type": "Microsoft.ServiceBus/namespaces",
                            "apiVersion": "[variables('sb_version')]",
                            "name": "[variables('sb_name')]",
                            "location": "[parameters('location')]",
                            "sku": {
                                "name": "Premium",
                                "tier": "Premium",
                                "capacity": 1
                            },
                            "identity": {
                                "type": "SystemAssigned"
                            },
                            "properties": {
                                "zoneRedundant": false,
                                "encryption": {
                                    "keySource": "Microsoft.KeyVault",
                                    "keyVaultProperties": [
                                        {
                                            // Ideally should specify a specific version, but no ARM template function to get this currently.
                                            "keyVaultUri": "[reference(variables('kv_name')).vaultUri]",
                                            "keyName": "[variables('sb_keyname')]"
                                        }
                                    ]
                                }
                            }
                        }
                    ]
                }
            }
        }
    ]
}

使用Azure CLI来部署它:

az group create -g rg-example -l westus2
az deployment group create -g rg-example -f template.json --parameters name=example

关于azure-devops - 如何创建利用 Key Vault 的幂等、可重新部署的 ARM 模板?循环依赖存在问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66803847/

相关文章:

git - 如何将多个电子邮件地址链接到 Azure DevOps 中的一个用户?

azure - 使用 Azure CLI 从变量创建 Azure Key Vault secret ,并在值中删除插入符号 ^ 字符

azure - 无法使用 Azure 中的服务主体获取经典 Web 角色

Azure REST API 位置筛选器

azure-resource-manager - ARM模板中是否可以有条件属性

azure - 是否可以更改单个 Key Vault Secret 的访问权限?

Azure Key Vault 保护证书

Azure 部署 [错误]进程 'appcmd.exe' 退出,代码为 '4312'

wpf - Azure DevOps - 有没有办法在管道中发布 Fx4.8 WPF 应用程序?

azure - 管道: cannot publish a file from artifacts directory