Agregue referencias de Key Vault a Azure Functions

⏱️5 min
Compartir:

Octubre de este año, una característica llamada Key Vault references fue GA 1. Esta es una función para almacenar secretos manejados por Azure Functions y App Service en Key Vault , y usarlos de forma transparente desde las aplicaciones (usar como variables de entorno sin estar al tanto de Key Vault desde las aplicaciones). Este artículo describe cómo lograr estas Key Vault references . Los contenidos básicos son los mismos que los descritos en el documento oficial de Microsoft 2, pero agregaré algunas notas y sugerencias por mi cuenta. Además, este artículo describe cómo implementar usando ARM Template y Azure CLI lugar de Azure portal , lo que lo ayudará a construir la infraestructura de CI / CD.

1. Agregue secretos y permisos a Key Vault

Agregue secretos y permisos de Azure Functions en Key Vault .

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}

Los derechos de acceso se establecen en la parte accessPolicies . En la propiedad llamada objectId , especifique la Managed ID de las Azure Functions destino. Managed ID se describe más adelante, pero son ID asignadas a Azure Functions que se pueden usar para identificar Azure Functions y administrar los derechos de acceso. Para los permissions , especifique los permisos que desea otorgar. En el ejemplo anterior, las Azure functions tendrán permiso para ver el secreto. Establezca los permisos aquí de acuerdo con la aplicación.

El secreto se establece en el recurso de Microsoft.KeyVault/vaults/secrets . Especifique el valor secreto en el value de las properties . En este ejemplo, se establece la clave de la cuenta de almacenamiento. También especifique cualquier secreto aquí según el propósito.

2. Agregue la configuración de la aplicación a Azure Functions

A continuación, implementemos la configuración de la aplicación. Para simplificar, solo se enumeran las configuraciones relevantes para las 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}

Dentro de la ARM Template , establezca los valores de la siguiente manera:

  1. Generar resourceId indica resourceId secreto (definido en la parte de variables )
  2. Obtenga el URI secreto de Key Vault con la propiedad secretUriWithVersion para el resourceId del paso 1
  3. Agregue la uri a la configuración de la aplicación en el formato @Microsoft.KeyVault(SecretUri={secret uri})

El resourceId y la reference que aparecen en los ejemplos de plantilla se denominan funciones de plantilla. Para obtener más información, consulte la documentación oficial de Microsoft 3.

3. Implemente recursos con atención a las dependencias

Cuando use Key Vault references , tenga en cuenta el orden de implementación. El orden básico es el siguiente:

  1. Recursos de Azure Functions ( Microsoft.Web/sites )
  2. Key Vault
  3. Ajustes de aplicaciones de Azure Functions
  4. Implementar zip de Azure Functions (artefactos de compilación)

Primero, implemente Azure Functions . Esto se debe a que cuando implementa Key Vault en el paso 2, la Managed ID para Azure Functions debe haberse emitido por adelantado para establecer la política de acceso a Key Vault . Managed ID se puede emitir con la siguiente plantilla.

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}

Especifique la identity la propiedad con el tipo SystemAssigned . En este momento, las Key Vault references solo están disponibles para el tipo de ID SystemAssigned por el SystemAssigned 2.

Sin embargo, aún no puede implementar la configuración de la aplicación en el paso 1. Porque en este momento, Key Vault no se implementa y no puede especificar un SecretUri , que es obligatorio para las Key Vault references . Después de implementar Key Vault en el paso 2, implemente la configuración de aplicaciones Azure Functions . Finalmente, implemente los artefactos de compilación de Azure Functions . La advertencia aquí es que debe implementar el zip de la aplicación después de que se haya implementado la configuración de la aplicación. Si despliega los artefactos de compilación primero y luego despliega los ajustes de la aplicación, la función desaparecerá.

Precauciones al configurar aplicaciones con la Azure CLI

El ejemplo anterior usa la ARM Template , pero, por supuesto, también puede aprovechar la Azure CLI . Si bien la ARM Template siempre sobrescribe la configuración de la aplicación existente, la Azure CLI puede agregar una nueva configuración a la configuración de la aplicación existente, reduciendo así las restricciones de dependencia anteriores. Por ejemplo, hemos declarado que la configuración de la aplicación en el paso 3 debe ser posterior a la implementación de Key Vault en el paso 2 y antes de extraer el zip en el paso 4. Pero si puede agregar (no sobrescribir) la configuración de la aplicación utilizando la Azure CLI , primero puede implemente las configuraciones de la aplicación que no sean las Key Vault references en el momento del paso 1, y después de implementar Key Vault o extraer el zip, luego agregue el resto de las configuraciones de aplicaciones relacionadas con las Key Vault references usando la Azure CLI .

Así se especifica la configuración de la aplicación para Key Vault en la Azure CLI .

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

Cabe señalar que debe establecer Key Vault references en el formato de $secretUri = '"@Microsoft.KeyVault(SecretUri={0})"' -f $url . Si escribe como $secretUri = "@Microsoft.KeyVault(SecretUri=${url})" , el último ) se establecerá incorrectamente y se producirá un error 4.

Otro punto a tener en cuenta son los permisos necesarios para ejecutar los comandos anteriores. El usuario o el principal del servicio que ejecuta este comando debe tener permiso de lectura para el secreto de Key Vault . En la plantilla de Key Vault descrita anteriormente, solo a Azure Functions les otorgó permiso de lectura, pero también otorguemos temporalmente permiso de lectura al ejecutor del comando.

4. Obtener un secreto en su aplicación

Todo lo que tiene que hacer es acceder a las variables de entorno en el código de su aplicación.

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");

Resumen

Este artículo describe cómo usar las Key Vault references que han sido GA desde octubre. El orden de implementación es un poco complicado, pero de lo contrario no debería ser demasiado difícil. Intenta usarlo.

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

Compartir:

Artículos relacionados