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

⏱️约3分钟
分享:

今年10月,称为“ Key Vault references的功能是GA 1。 此功能用于将由Azure FunctionsApp Service处理的机密存储在Key Vault ,并在应用程序中透明地使用它们(用作环境变量,而无需从应用程序中了解Key Vault )。 本文介绍如何实现此Key Vault references 。基本内容与Microsoft官方文档2中描述的内容相同,但是我将自行添加一些注释和技巧。 此外,本文介绍如何使用ARM TemplateAzure CLI代替Azure portal来实施,这将帮助您构建CI / CD基础结构。

1.向Key Vault添加机密和权限

Key Vault添加Azure Functions机密和权限。

json
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": false
58 },
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 FunctionsManaged IDManaged ID将在后面描述,但是它们是分配给Azure Functions ID,可用于标识Azure Functions和管理访问权限。 对于permissions ,指定要授予的权限。在上面的示例中, Azure functions将有权查看此机密。根据应用程序在此处设置任何权限。

机密在Microsoft.KeyVault/vaults/secrets的资源中设置。指定的秘密值valueproperties 。在此示例中,设置了存储帐户的密钥。还要根据目的在此处指定任何秘密。

2.将应用程序设置添加到Azure Functions

接下来,让我们部署应用程序设置。为简单起见,仅列出与Key Vault references相关的设置。

json
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 ,设置值如下:

  1. 生成resourceId指示秘密资源(定义variables部分)
  2. 使用属性secretUriWithVersion获取步骤1的resourceId的Key Vault的秘密URI。
  3. 将uri以@Microsoft.KeyVault(SecretUri={secret uri})的格式添加到应用程序设置中

出现在模板示例中的resourceIdreference称为模板函数。有关更多信息,请参见正式的Microsoft文档3

3.部署资源时要注意依赖关系

使用Key Vault references ,请记住部署顺序。 基本顺序如下:

  1. Azure Functions资源( Microsoft.Web/sites
  2. Key Vault
  3. Azure Functions程序设置
  4. 部署Azure Functions zip(构建工件)

首先,部署Azure Functions 。 这是因为在步骤2中部署Key Vault时,必须预先发布Azure FunctionsManaged ID才能将访问策略设置为Key Vault 。 可以使用以下模板来发布Managed ID

json
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": true
33 },
34 "location": "[resourceGroup().location]",
35 "kind": "functionapp"
36}

使用SystemAssigned类型指定属性identity 。目前, Key Vault references仅适用于ID为2SystemAssigned类型。

但是,您尚无法在步骤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 CLIKey Vault指定应用程序设置的方法。

powershell
1try {
2 $ret = az keyvault secret show --vault-name $keyVaultName --name $secretName
3}
4catch
5{
6 $message = $_.Exception.message
7 throw "Failed to get key vault secret: ${message}."
8}
9$secretObj = $ret | ConvertFrom-Json
10$url = $secretObj.id
11$secretUri = '"@Microsoft.KeyVault(SecretUri={0})"' -f $url
12
13# Add appsettings for azure functions
14az 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.在您的应用程序中获取秘密

您所要做的只是访问应用程序代码中的环境变量。

csharp
1// C#
2var env = System.Environment.GetEnvironmentVariable("YOUR_SECRET", EnvironmentVariableTarget.Process);
3
4// Javascript
5let env = process.env["YOUR_SECRET"];
6
7// Java
8String env = System.getenv("YOUR_SECRET");

摘要

本文介绍了如何使用自10月以来一直是GA的Key Vault references 。部署的顺序有点棘手,但否则应该不会太困难。 请尝试使用它。

Footnotes

  1. Key Vault references in App Service and Azure Functions are now available

  2. Use Key Vault references for App Service and Azure Functions 2

  3. Resource functions for Azure Resource Manager templates

  4. Incorrect config value set

分享:

相关文章

将Azure资源描述为ARM Template
Guides

将Azure资源描述为ARM Template

ARM Template是定义Azure资源的json文件。本文介绍如何高效创建ARM Template来部署新资源。

mark241
将后端连接到Azure API管理
Guides

将后端连接到Azure API管理

了解如何使用ARM模板向API管理添加API。使用operations、policy和backend资源连接到后端。

mark241