Post

Configuración y Secretos con Azure Application Configuration y Key Vault

En el universo en constante evolución de la tecnología en la nube, la gestión eficiente y segura de las configuraciones de las aplicaciones y los secretos es fundamental. Los servicios como Azure Application Configuration (AAC) y Azure Key Vault surgen para responder a estas necesidades, ofreciendo un enfoque centralizado y seguro para la gestión de la configuración y el almacenamiento de secretos, respectivamente. Al integrar estos servicios con nuestras aplicaciones de nube desplegadas por ejemplo en Azure Functions, nos embarcamos en un camino hacia una gestión más eficiente y segura de nuestras aplicaciones en la nube. Pero, ¿cómo se hace? Bueno, eso es precisamente lo que estamos a punto de explorar.

Azure Application Configuration (AAC) es un servicio de Azure que facilita la gestión centralizada de las configuraciones de las aplicaciones. Se puede pensar en él como un almacén de datos accesible en tiempo real, que ayuda a administrar todo el entorno de configuración de nuestras aplicaciones. Este servicio puede integrarse con Azure Key Vault para proporcionar un modelo unificado de acceso a secretos y variables de configuración. Esto significa que nuestras aplicaciones pueden obtener tanto sus variables de configuración como los secretos de una sola fuente, simplificando el desarrollo y manteniendo todo organizado y seguro.

Para efectos de éste artículo exploraremos cómo aplicar éstos dos servicios a una Azure Function en el modelo Isolated. Este nuevo modelo que presenta varias ventajas frente al tradicional en el que la aplicación corre en el mismo proceso del host presenta unos aspectos interesantes en la configuración debido a la inyección de dependencias que es clave en esta innovación. Por ende, he decidido plantear éste ejemplo para observar como resolvemos una integración entre estos tres elementos; más aún cuando desarrollando una aplicación de punta me enfrenté a este reto donde para usar AAC en nuestro código de funciones, se deben hacer ajustes en el archivo Program.cs y también es necesario inyectar el objeto de configuración en el código de la función.

1
2
3
4
5
6
7
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .Build();

host.Run();

Este código crea una nueva instancia de Host utilizando la clase HostBuilder usada para crear aplicaciones administradas. Y es aquí comenzaremos inyectando el servicio de configuración.

Para esto usamos el métodoConfigureAppConfigurationque configura los valores de configuración de la aplicación mediante la adición de valores de múltiples fuentes. Luego a través de la cadena de métodos llamamos a AddAzureAppConfigurationque nos permite referenciar a la instancia del servicio que ya hemos creado en Azure.

Primero obtenemos la cadena de conexión a la instancia. Como buena práctica creamos una variable de ambiente con ésta cadena (así evitamos dejarla en el código o en un archivo de configuración que pueda enviarse accidentalmente al servidor de código fuente). Lo mejor de todo es que en desarrollo el valor sale de las variables del OS y luego en producción, se extraen de los App Settings de la función.

Démosle el nombre a la variable deAppSettingsConnectionString y traigámosla usando Environment.GetEnvironmentVariable. Luego con el método options.Connect(cs) nos conectamos al servicio.

Finalmente, el método ConfigureFunctionsWorkerDefaultsestablece la configuración por defecto del worker de Azure Functions, y el método Build() construye la instancia de Host y el método host.Run() ejecuta el pipeline de HostBuilder para iniciar la aplicación.

1
2
3
4
5
6
7
8
9
10
11
var host = new HostBuilder()
    .ConfigureAppConfiguration(config =>
    {
        string? cs = Environment.GetEnvironmentVariable("AppSettingsConnectionString");
        var settings = config.Build();
        options.Connect(cs);
    })
    .ConfigureFunctionsWorkerDefaults()
    .Build();

host.Run();

Procedamos a configurar el uso de Key Vault. Esto opera a nivel de las opciones del servicio de Azure App Configuration; específicamente usando el método de extensión ConfigureKeyVault ajustando su credencial de acceso a DefaultAzureCredentialque proporciona la credencial para autenticar una aplicación a los servicios de Azure Key Vault utilizando la cadena de credenciales predeterminada del Azure SDK. Esto significa que intenta utilizar los métodos de autenticación disponibles en orden de prioridad, como las variables de entorno, la identidad administrada o incluso el inicio de sesión en Visual Studio, entre otros.

El código final de Program.csse vería así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using Azure.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureAppConfiguration(config =>
    {
        string? cs = Environment.GetEnvironmentVariable("AppSettingsConnectionString");
        var settings = config.Build();
        config.AddAzureAppConfiguration(options =>
        {
            options.Connect(cs)
                .ConfigureKeyVault(kv =>
                {
                    kv.SetCredential(new DefaultAzureCredential());
                });
        });
    })
    .ConfigureFunctionsWorkerDefaults()
    .Build();

host.Run();

Precisamente, en tiempo de desarrollo, vamos a necesitar que Visual Studio pueda acceder al Key Vault en Azure. Entonces se debe autenticar el IDE contra la suscripción en la cual reside el Key Vault. Esto se puede hacer a través del setting: Azure Service Authentication usando una cuenta Microsoft con el acceso adecuado.

Autorizando a Visual Studio para acceder a suscripción de Azure

Sin embargo, esto no basta. Es necesario también autenticarse contra Azure con la misma cuenta desde la máquina de desarrollo. Esto se hace bien sea a través del módulo az de PowerShell usando el comando Connect-AzAccount o si se tiene azd cli , con azd auth login. Ambos comandos lanzan una ventana de browser para hacer el respectivo login.

Hay que recordar también que a pesar que la aplicación consultará los secretos a través de AAC, esto no quiere decir que la aplicación no tenga que tener también privilegios de acceso sobre el AKV. Unas instrucciones muy sencillas para autorizar a un servicio como la Azure Function que estamos usando de ejemplo, se encuentra aquí.

Ya con todos estos preparativos podemos ir a la lógica de nuestra aplicación en el código de nuestra Azure Function. Primero creamos un constructor que permita al sistema de inyección de dependencias instanciar el objeto de configuración que ya hemos configurado para conectarse a AAC:

1
2
3
4
5
6
//Setting up the configuration
private readonly IConfiguration _configuration;
public FxPharmaVisitSummary(IConfiguration configuration)
{
    _configuration = configuration;
}

Y luego ya dentro del código llamamos al secreto o variable de configuración que queramos de una manera super sencilla:

1
2
openAiKey = _configuration["ModelKey"];
openAiDeploymentOrModelName = _configuration["ModelName"];

Aquí claramente ModelKey es un secreto y ModelNamees una variable de configuración.

En conclusión, el uso de Azure Application Configuration con Azure Key Vault es una excelente manera de mantener nuestras configuraciones y secretos seguros y centralizados en la nube. Aunque la configuración puede ser un poco complicada al principio, es fácil de implementar una vez que se tienen en cuenta estos detalles. Espero que este artículo les haya sido útil. ¡Hasta la próxima!

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.