使用 ARM 模板将 Azure KeyVault 机密从 KeyVault 获取到应用服务

Posted

技术标签:

【中文标题】使用 ARM 模板将 Azure KeyVault 机密从 KeyVault 获取到应用服务【英文标题】:Get Azure KeyVault Secrets from the KeyVault to an App Service using ARM Templates 【发布时间】:2022-01-22 16:26:06 【问题描述】:

在 Microsoft KeyVault 资源中我有一个秘密:

        
          "type": "secrets",
          "apiVersion": "2016-10-01",
          "name": "mongodb",
          "location": "[resourceGroup().location]",
          "dependsOn": [
            "[resourceId('Microsoft.KeyVault/vaults', variables('vault').name)]"
          ],
          "properties": 
            "attributes": 
              "enabled": true
            ,
            "value": "[listConnectionStrings(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosAccountName')), '2019-12-12').connectionStrings[0].connectionString]"
          
        

我想提取此值并将其存储在应用服务中的键值对中。

        "siteConfig": 
          "appSettings": [
            
              "name": "COSMOS_CONNECTION_STRING",
              "value": ""
            
          ]
        

它们在同一个资源组中。

如何从密钥库中获取价值?

【问题讨论】:

【参考方案1】:

首先,您需要授予App ServiceKeyVault 读取密钥的权限,这是通过创建Access Policy 来完成的。

这是由以下人员完成的:

 
      "type": "Microsoft.KeyVault/vaults/accessPolicies",
      "apiVersion": "2016-10-01",
      "name": "[concat( variables('vault').name, '/replace')]",
      "dependsOn": [
        "[resourceId('Microsoft.KeyVault/vaults', variables('vault').name)]",
      ],
      "properties": 
        "accessPolicies": [
          
            "tenantId": "[subscription().tenantId]",
            "objectId": "[reference(resourceId('Microsoft.Web/sites', variables('AppService').name), '2016-08-01', 'Full').identity.principalId]",
            "permissions": 
              "keys": [
              ],
              "secrets": [
                "Get",
                "List"
              ],
              "certificates": []
            
          
        ]
      
    

然后您可以通过以下方式访问密钥:

@Microsoft.KeyVault(VaultName=myvault;SecretName=mysecret)

myvault 是您的保管库的名称,并且 mysecret 是您的密钥的名称

这将创建一个KeyVault Reference

【讨论】:

【参考方案2】:

要获取/读取应用服务的 Azure Key Vault Secrets,您需要创建一个保管库并授予您的应用访问它的权限。

为您之前创建的应用程序身份创建一个access policy in Key Vault。启用此策略的“获取”秘密权限。不要配置“授权应用程序”或applicationId 设置,因为这与托管标识不兼容。

`


    //...
    "resources": [
        
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageAccountName')]",
            //...
    ,
    
        "type": "Microsoft.Insights/components",
        "name": "[variables('appInsightsName')]",
        //...
    ,
    
        "type": "Microsoft.Web/sites",
        "name": "[variables('functionAppName')]",
        "identity": 
            "type": "SystemAssigned"
        ,
        //...
        "resources": [
            
                "type": "config",
                "name": "appsettings",
                //...
                "dependsOn": [
                    "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                    "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                    "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('storageConnectionStringName'))]",
                    "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('appInsightsKeyName'))]"
                ],
                "properties": 
                    "AzureWebJobsStorage": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringResourceId')).secretUriWithVersion, ')')]",
                    "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringResourceId')).secretUriWithVersion, ')')]",
                    "APPINSIGHTS_INSTRUMENTATIONKEY": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('appInsightsKeyResourceId')).secretUriWithVersion, ')')]",
                    "WEBSITE_ENABLE_SYNC_UPDATE_SITE": "true"
                    //...
                
            ,
            
                "type": "sourcecontrols",
                "name": "web",
                //...
                "dependsOn": [
                    "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                    "[resourceId('Microsoft.Web/sites/config', variables('functionAppName'), 'appsettings')]"
                ],
            
        ]
    ,
    
        "type": "Microsoft.KeyVault/vaults",
        "name": "[variables('keyVaultName')]",
        //...
        "dependsOn": [
            "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
        ],
        "properties": 
            //...
            "accessPolicies": [
                
                    "tenantId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.tenantId]",
                    "objectId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.principalId]",
                    "permissions": 
                        "secrets": [ "get" ]
                    
                
            ]
        ,
        "resources": [
            
                "type": "secrets",
                "name": "[variables('storageConnectionStringName')]",
                //...
                "dependsOn": [
                    "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                    "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
                ],
                "properties": 
                    "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),'2019-09-01').key1)]"
                
            ,
            
                "type": "secrets",
                "name": "[variables('appInsightsKeyName')]",
                //...
                "dependsOn": [
                    "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                    "[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
                ],
                "properties": 
                    "value": "[reference(resourceId('microsoft.insights/components/', variables('appInsightsName')), '2019-09-01').InstrumentationKey]"
                
            
        ]
    
]

有关通过 arm 模板获取应用服务的密钥库机密的更多详细信息,请参阅此Microsoft Documentation

【讨论】:

以上是关于使用 ARM 模板将 Azure KeyVault 机密从 KeyVault 获取到应用服务的主要内容,如果未能解决你的问题,请参考以下文章

Azure Keyvault 通过 ARM 添加 Function MSI

使用客户管理的密钥进行 Azure 存储帐户加密

Azure RM 模板。使用 Key Vault 密码部署副本 VM

KeyVault 模板 - 多个访问策略

如何将 Azure 管道变量传递给 AzureResourceManagerTemplateDeployment@3 任务使用的 ARM 模板?

是否可以使用 ARM 模板重新部署 Azure 数据工厂