将密钥保管库引用添加到Azure函数

这篇文章发布于一年多前,信息可能已过时。
今年10月,称为“ Key Vault references的功能是GA 1。
此功能用于将由Azure Functions和App Service处理的机密存储在Key Vault ,并在应用程序中透明地使用它们(用作环境变量,而无需从应用程序中了解Key Vault )。
本文介绍如何实现此Key Vault references 。基本内容与Microsoft官方文档2中描述的内容相同,但是我将自行添加一些注释和技巧。
此外,本文介绍如何使用ARM Template和Azure CLI代替Azure portal来实施,这将帮助您构建CI / CD基础结构。
1.向Key Vault添加机密和权限
在Key Vault添加Azure Functions机密和权限。
1{2 "$schema": "https://schema.management.azure.com/schemas/2018-05-01/deploymentTemplate.json#",3 "contentVersion": "1.0.0.0",4 "parameters": {5 "keyVaultName": {6 "type": "string",7 "metadata": {8 "description": "Key Vault Name"9 }10 },11 "secretName": {12 "type": "string",13 "metadata": {14 "description": "Secret Name"15 }16 },17 "functionAppName": {18 "type": "string",19 "metadata": {20 "description": "Function App Name"21 }22 },23 "storageAccountName": {24 "type": "string",25 "metadata": {26 "description": "Storage Account Name"27 }28 }29 },30 "variables": {},31 "resources": [32 {33 "name": "[parameters('keyVaultName')]",34 "type": "Microsoft.KeyVault/vaults",35 "apiVersion": "2018-02-14",36 "location": "[resourceGroup().location]",37 "properties": {38 "tenantId": "[subscription().tenantId]",39 "sku": {40 "family": "A",41 "name": "standard"42 },43 "accessPolicies": [44 {45 "tenantId": "[subscription().tenantId]",46 "objectId": "[reference(resourceId('Microsoft.Web/sites', parameters('functionAppName')), '2016-03-01', 'Full').identity.principalId]",47 "permissions": {48 "keys": [],49 "secrets": ["get"],50 "certificates": [],51 "storage": []52 }53 }54 ],55 "enabledForDeployment": false,56 "enabledForDiskEncryption": false,57 "enabledForTemplateDeployment": false58 },59 "resources": [60 {61 "name": "[concat(parameters('keyVaultName'), '/', parameters('secretName'))]",62 "type": "Microsoft.KeyVault/vaults/secrets",63 "apiVersion": "2018-02-14",64 "dependsOn": [65 "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]"66 ],67 "properties": {68 "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2015-05-01-preview').key1)]"69 }70 }71 ]72 }73 ]74}访问权限在accessPolicies部分中设置。在名为objectId的属性中,指定目标Azure Functions的Managed ID 。 Managed ID将在后面描述,但是它们是分配给Azure Functions ID,可用于标识Azure Functions和管理访问权限。
对于permissions ,指定要授予的权限。在上面的示例中, Azure functions将有权查看此机密。根据应用程序在此处设置任何权限。
机密在Microsoft.KeyVault/vaults/secrets的资源中设置。指定的秘密值value的properties 。在此示例中,设置了存储帐户的密钥。还要根据目的在此处指定任何秘密。
2.将应用程序设置添加到Azure Functions
接下来,让我们部署应用程序设置。为简单起见,仅列出与Key Vault references相关的设置。
1{2 "$schema": "https://schema.management.azure.com/schemas/2018-05-01/deploymentTemplate.json#",3 "contentVersion": "1.0.0.0",4 "parameters": {5 "keyVaultName": {6 "type": "string",7 "metadata": {8 "description": "Key Vault Name"9 }10 },11 "secretName": {12 "type": "string",13 "metadata": {14 "description": "Secret Name"15 }16 },17 "functionAppName": {18 "type": "string",19 "metadata": {20 "description": "Function App Name"21 }22 }23 },24 "variables": {25 "secretResourceId": "[resourceId(resourceGroup().name, 'Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), 'parameters('secretName')')]"26 },27 "resources": [28 {29 "name": "[concat(parameters('functionAppName'), '/appsettings')]",30 "type": "Microsoft.Web/sites/config",31 "apiVersion": "2018-11-01",32 "location": "[resourceGroup().location]",33 "properties": {34 "YOUR_SECRET": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('secretResourceId'), '2018-02-14').secretUriWithVersion, ')')]"35 }36 }37 ]38}在ARM Template ,设置值如下:
- 生成
resourceId指示秘密资源(定义variables部分) - 使用属性
secretUriWithVersion获取步骤1的resourceId的Key Vault的秘密URI。 - 将uri以
@Microsoft.KeyVault(SecretUri={secret uri})的格式添加到应用程序设置中
出现在模板示例中的resourceId和reference称为模板函数。有关更多信息,请参见正式的Microsoft文档3。
3.部署资源时要注意依赖关系
使用Key Vault references ,请记住部署顺序。
基本顺序如下:
Azure Functions资源(Microsoft.Web/sites)Key VaultAzure Functions程序设置- 部署
Azure Functionszip(构建工件)
首先,部署Azure Functions 。
这是因为在步骤2中部署Key Vault时,必须预先发布Azure Functions的Managed ID才能将访问策略设置为Key Vault 。
可以使用以下模板来发布Managed ID 。
1{2 "apiVersion": "2016-03-01",3 "name": "[parameters('functionAppName')]",4 "type": "Microsoft.Web/sites",5 "identity": {6 "type": "SystemAssigned"7 },8 "properties": {9 "name": "[parameters('functionAppName')]",10 "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",11 "hostNameSslStates": [12 {13 "name": "[concat(variables('functionAppName'),'.azurewebsites.net')]",14 "sslState": "Disabled",15 "virtualIP": null,16 "thumbprint": null,17 "toUpdate": null,18 "hostType": "Standard"19 },20 {21 "name": "[concat(variables('functionAppName'),'.scm.azurewebsites.net')]",22 "sslState": "Disabled",23 "virtualIP": null,24 "thumbprint": null,25 "toUpdate": null,26 "hostType": "Repository"27 }28 ],29 "siteConfig": null,30 "clientAffinityEnabled": false,31 "reserved": false,32 "httpsOnly": true33 },34 "location": "[resourceGroup().location]",35 "kind": "functionapp"36}使用SystemAssigned类型指定属性identity 。目前, Key Vault references仅适用于ID为2的SystemAssigned类型。
但是,您尚无法在步骤1上部署应用程序设置。因为此时,尚未部署Key Vault并且您无法指定SecretUri (对于Key Vault references是必需的)。
在步骤2中部署Key Vault之后,请部署Azure Functions程序设置。
最后,部署Azure Functions构建工件。需要注意的是,在部署了appsettings之后,您需要部署zip文件。如果先部署构建工件,然后再部署应用程序设置,则该功能将消失。
使用Azure CLI设置应用程序时的注意事项
上面的示例使用ARM Template ,但是您当然也可以利用Azure CLI 。
虽然ARM Template始终会覆盖现有应用程序设置,但Azure CLI可以将新设置添加到现有应用程序设置,从而减少了上述依赖关系约束。
例如,我们已经声明,步骤3中的应用程序设置必须在步骤2中的Key Vault部署之后并且在步骤4中解压缩zip之前。但是,如果可以使用Azure CLI添加(而不是覆盖)应用程序设置,则可以首先请在步骤1的时间部署除Key Vault references以外的应用程序设置,并在部署Key Vault或提取zip之后,然后使用Azure CLI添加与Key Vault references相关的其余应用程序设置。
这是在Azure CLI为Key Vault指定应用程序设置的方法。
1try {2 $ret = az keyvault secret show --vault-name $keyVaultName --name $secretName3}4catch5{6 $message = $_.Exception.message7 throw "Failed to get key vault secret: ${message}."8}9$secretObj = $ret | ConvertFrom-Json10$url = $secretObj.id11$secretUri = '"@Microsoft.KeyVault(SecretUri={0})"' -f $url12 13# Add appsettings for azure functions14az functionapp config appsettings set --name $functionAppName --resource-group $resourceGroup --settings YOUR_SECRET=$secretUri应当注意,您需要以$secretUri = '"@Microsoft.KeyVault(SecretUri={0})"' -f $url的格式设置Key Vault references 。如果您这样写$secretUri = "@Microsoft.KeyVault(SecretUri=${url})" ,则最后一个)将设置错误,并且会发生错误4。
要注意的另一点是执行上述命令所需的权限。运行此命令的用户或服务主体必须具有Key Vault机密的读取权限。在上述的Key Vault模板中,仅授予Azure Functions读取权限,但让我们也暂时将读取权限授予命令执行者。
4.在您的应用程序中获取秘密
您所要做的只是访问应用程序代码中的环境变量。
1// C#2var env = System.Environment.GetEnvironmentVariable("YOUR_SECRET", EnvironmentVariableTarget.Process);3 4// Javascript5let env = process.env["YOUR_SECRET"];6 7// Java8String env = System.getenv("YOUR_SECRET");摘要
本文介绍了如何使用自10月以来一直是GA的Key Vault references 。部署的顺序有点棘手,但否则应该不会太困难。
请尝试使用它。


