Compartir a través de


Visión general de las integraciones de .NET AspireAzure

Azure es la plataforma en la nube más popular para compilar e implementar aplicaciones .NET. El SDK de Azure para .NET permite administrar y usar fácilmente los servicios de Azure. .NET Aspire proporciona un conjunto de integraciones con servicios de Azure. En este artículo se detallan algunos aspectos comunes de todas las integraciones de Azure en .NET Aspire y se pretende ayudarle a comprender cómo usarlos.

Agregar recursos de Azure

Todas las integraciones de hospedaje de .NET AspireAzure exponen recursos Azure y por convención se agregan mediante AddAzure* API. Al añadir estos recursos a tu host de aplicación .NET Aspire, representan un servicio Azure. La API de AddAzure* devuelve un IResourceBuilder<T> donde T es el tipo de recurso de Azure. Estas interfaces de IResourceBuilder<T> (constructor) proporcionan una API fluente que permite configurar el recurso subyacente de Azure dentro del modelo de aplicación de .

Experiencia típica para desarrolladores

Cuando el host de la aplicación de contiene recursos de y lo ejecuta localmente (experiencia típica del desarrollador F5 o ), los recursos de se aprovisionan en la suscripción de . Esta funcionalidad le permite a usted como desarrollador depurar estos elementos localmente en el contexto del host de su aplicación.

.NET .NET Aspire pretende minimizar los costos de forma predeterminada para básico o unidad de mantenimiento de existencias (SKU) estándar para sus integraciones de Azure. Aunque se proporcionan estos valores predeterminados razonables, puede personalizar los recursos de Azure para satisfacer sus necesidades. Además, algunas integraciones admiten emuladores o contenedores, que son útiles para el desarrollo, las pruebas y la depuración locales. De forma predeterminada, al ejecutar la aplicación localmente, los recursos de Azure usan el servicio Azure real. Sin embargo, puede configurarlos para que usen emuladores o contenedores locales, evitando los costos asociados con el servicio Azure real durante el desarrollo local.

Emuladores locales

Algunos servicios Azure se pueden ejecutar localmente en emuladores. Actualmente, .NET Aspire admite los siguientes emuladores de Azure:

Integración de hospedaje Descripción
Azure Cosmos DB Llame a AzureCosmosExtensions.RunAsEmulator en el IResourceBuilder<AzureCosmosDBResource> para configurar el Cosmos DB recurso para ser emulado con la API NoSQL.
Azure Event Hubs Llame a AzureEventHubsExtensions.RunAsEmulator en el IResourceBuilder<AzureEventHubsResource> para configurar el recurso de Event Hubs para que sea emulado.
Azure almacenamiento Llame a AzureStorageExtensions.RunAsEmulator en el IResourceBuilder<AzureStorageResource> para configurar el recurso de almacenamiento que se va a emular con Azurite.

Para que los recursos de Azure usen los emuladores locales, encadena una llamada al método RunAsEmulator del generador de recursos Azure. Este método configura el recurso Azure para usar el emulador local en lugar del servicio Azure real.

Importante

Llamar a cualquiera de las API de RunAsEmulator disponibles en un constructor de recursos de Azure no afecta el manifiesto de publicación de . Al publicar la aplicación, archivo bicep generado refleja el servicio Azure real, no el emulador local.

Contenedores locales

Algunos servicios Azure se pueden ejecutar localmente en contenedores. Para ejecutar un servicio Azure localmente en un contenedor, encadene una llamada al método RunAsContainer en el generador de recursos de Azure. Este método configura el recurso Azure para que se ejecute localmente en un contenedor en lugar del servicio Azure real.

Actualmente, .NET Aspire admite los siguientes servicios Azure como contenedores:

Integración de hospedaje Detalles
Azure Cache for Redis Ejecute AzureRedisExtensions.RunAsContainer en IResourceBuilder<AzureRedisCacheResource> para configurarlo y ejecutarlo localmente en un contenedor, basado en la imagen de docker.io/library/redis.
Azure PostgreSQL Server flexible Llame a AzurePostgresExtensions.RunAsContainer en el IResourceBuilder<AzurePostgresFlexibleServerResource> para configurarlo localmente en un contenedor utilizando la imagen de docker.io/library/postgres.
Azure SQL Server Llame al AzureSqlExtensions.RunAsContainer en el IResourceBuilder<AzureSqlServerResource> para ajustarlo de manera que se ejecute localmente en un contenedor, utilizando la imagen mcr.microsoft.com/mssql/server.

Nota

Al igual que los emuladores, llamar a RunAsContainer en un generador de recursos de Azure no afecta al manifiesto de publicación . Al publicar tu aplicación, el archivo Bicep generado refleja el servicio Azure real, no el contenedor local.

Descripción de las API de integración de Azure

La fuerza de .NET.NET Aspirereside en su capacidad para proporcionar un ciclo interno asombroso para desarrolladores. Las integraciones de Azure no son diferentes. Proporcionan un conjunto de API y patrones comunes que se comparten en todos los recursos de Azure. Estas APIs y patrones están diseñados para facilitar el trabajo con recursos Azure de manera coherente.

En la sección de contenedores precedentes, has visto cómo ejecutar Azure servicios en contenedores de forma local. Si está familiarizado con .NET.NET Aspire, es posible que se pregunte cómo llamar a AddAzureRedis("redis").RunAsContainer() para obtener un contenedor de docker.io/library/redis local difiere de AddRedis("redis"), ya que ambos dan como resultado el mismo contenedor local.

La respuesta es que no hay ninguna diferencia al ejecutarse localmente. Sin embargo, cuando se publican, consigues recursos diferentes:

API Modo de ejecución Modo de publicación
AddAzureRedis("redis"). RunAsContainer() Contenedor local Redis Azure Cache for Redis
AddRedis("redis") Contenedor de Redis local Azure aplicación contenedora con Redis imagen

Lo mismo sucede con los servicios SQL y PostgreSQL:

API Modo de ejecución Modo de publicación
AddAzurePostgresFlexibleServer("postgres").RunAsContainer() Contenedor PostgreSQL local Azure PostgreSQL Server flexible
AddPostgres("postgres") Contenedor local PostgreSQL Azure aplicación contenedor con imagen PostgreSQL
AddAzureSqlServer("sql").RunAsContainer() Contenedor local SQL Server Azure SQL Server
AddSqlServer("sql") Contenedor local SQL Server Azure Aplicación de contenedor con la imagen SQL Server

Para obtener más información sobre la diferencia entre los modos de ejecución y publicación, consulte .NET.NET Aspire host de la aplicación: Contexto de ejecución.

Infraestructura como código

El SDK de Azure para .NET proporciona el 📦Azure, así como el paquete NuGet de aprovisionamiento y un conjunto de paquetes específicos de aprovisionamiento del servicio Azure. Estas Azure bibliotecas de aprovisionamiento facilitan la especificación declarativa de Azure infraestructura de forma nativa en .NET. Sus API le permiten escribir infraestructura orientada a objetos en C#, lo que da lugar a Bicep. Bicep es un de lenguaje específico del dominio (DSL) para implementar Azure recursos mediante declaración.

Aunque es posible aprovisionar Azure recursos manualmente, .NET Aspire simplifica el proceso proporcionando un conjunto de API para expresar recursos Azure. Estas API están disponibles como métodos de extensión en .NET AspireAzure bibliotecas de hospedaje, ampliando la interfaz IDistributedApplicationBuilder. Al añadir recursos Azure al host de la aplicación, se añade implícitamente la funcionalidad de aprovisionamiento adecuada. En otras palabras, no es necesario llamar directamente a ninguna API de aprovisionamiento.

Dado que .NET Aspire modela recursos Azure dentro de integraciones de hospedaje Azure, el SDK de Azure se utiliza para aprovisionar estos recursos. Se generan archivos de Bicep que definen los recursos Azure necesarios. Los archivos bicep generados se crean junto al archivo de manifiesto cuando publicas tu aplicación.

Hay varias maneras de influir en los archivos Bicep generados:

Aprovisionamiento local y Azure.Provisioning

Para evitar la confusión de términos y ayudar a aclarar el "aprovisionamiento", es importante comprender la distinción entre el aprovisionamiento local y el aprovisionamientoAzure:

  • Aprovisionamiento local:

    De forma predeterminada, cuando se llama a cualquiera de las API de integración de hospedaje de Azure para agregar recursos de Azure, se llama implícitamente a la API de AddAzureProvisioning(IDistributedApplicationBuilder). Esta API registra los servicios en el contenedor de inyección de dependencias (DI) que se utilizan para proveer los recursos Azure cuando se inicia el host de la aplicación. Este concepto se conoce como aprovisionamiento local. Para obtener más información, consulte Azure aprovisionamiento local.

  • Azure.Provisioning:

    Azure.Provisioning hace referencia al paquete NuGet y es un conjunto de bibliotecas que permite usar C# para generar Bicep. El Azure las integraciones de hospedaje en .NET Aspire usar estas bibliotecas en segundo plano para generar archivos de Bicep que definen los recursos de Azure que necesita. Para obtener más información, vea Azure.Provisioning personalización.

Personalización de Azure.Provisioning

Todas las integraciones de alojamiento de .NET AspireAzure exponen varios recursos de Azure, y todas son subclases del tipo AzureProvisioningResource, que a su vez hereda de AzureBicepResource. Esto habilita extensiones que están restringidas genéricamente a este tipo de dato, permitiendo que una API articulada personalice la infraestructura a su gusto. Aunque .NET.NET Aspire proporciona valores predeterminados, puede influir en el Bicep generado mediante estas APIs.

Configuración de la infraestructura

Independientemente del recurso Azure con el que trabajes, para configurar su infraestructura subyacente, se encadena una llamada al método de extensión ConfigureInfrastructure. Este método permite personalizar la infraestructura del recurso de Azure pasando un delegado de configure de tipo Action<AzureResourceInfrastructure>. El tipo AzureResourceInfrastructure es una subclase del Azure.Provisioning.Infrastructure. Este tipo expone una superficie de API masiva para configurar la infraestructura subyacente del recurso Azure.

Tenga en cuenta el ejemplo siguiente:

var sku = builder.AddParameter("storage-sku");

var storage = builder.AddAzureStorage("storage")
    .ConfigureInfrastructure(infra =>
    {
        var resources = infra.GetProvisionableResources();

        var storageAccount = resources.OfType<StorageAccount>().Single();

        storageAccount.Sku = new StorageSku
        {
            Name = sku.AsProvisioningParameter(infra)
        };
    });

El código anterior:

  • Agrega un parámetro denominado storage-sku.
  • Agrega almacenamiento Azure con la API AddAzureStorage, denominada storage.
  • Encadena una llamada a ConfigureInfrastructure para personalizar la infraestructura de almacenamiento de Azure:

Esto ejemplifica introducir un parámetro externo en la infraestructura de almacenamiento de Azure, lo que da como resultado el archivo Bicep generado que refleja la configuración deseada.

Agregar Azure a la infraestructura

No todos los servicios Azure se exponen como integraciones de .NET Aspire. Aun cuando podrían estar disponibles en otro momento, todavía puede habilitar servicios que están disponibles en bibliotecas Azure.Provisioning.*. Imagine un escenario en el que usted tiene un servicio de trabajo responsable de administrar un Azure Registro de Contenedores. Ahora imagine que un proyecto host de aplicación tiene una dependencia del paquete NuGet .Provisioning.ContainerRegistry .

Puede usar la API de AddAzureInfrastructure para agregar la infraestructura de Azure Container Registry al host de la aplicación:

var acr = builder.AddAzureInfrastructure("acr", infra =>
{
    var registry = new ContainerRegistryService("acr")
    {
        Sku = new()
        {
            Name = ContainerRegistrySkuName.Standard
        },
    };
    infra.Add(registry);

    var output = new ProvisioningOutput("registryName", typeof(string))
    {
        Value = registry.Name
    };
    infra.Add(output);
});

builder.AddProject<Projects.WorkerService>("worker")
       .WithEnvironment(
            "ACR_REGISTRY_NAME",
            new BicepOutputReference("registryName", acr.Resource));

El código anterior:

  • Llama a AddAzureInfrastructure con un nombre de acr.
  • Proporciona un delegado de configureInfrastructure para personalizar la infraestructura de Azure Container Registry:
    • Crea una instancia de un ContainerRegistryService con el nombre acr y una SKU estándar.
    • Agrega el servicio Azure Container Registry a la variable infra.
    • Crea una instancia de un ProvisioningOutput con el nombre registryName, un tipo de stringy un valor que corresponde al nombre del Azure Container Registry.
    • Agrega la salida a la variable infra.
  • Agrega un proyecto llamado worker al constructor.
  • Encadena una llamada a WithEnvironment para establecer la variable de entorno ACR_REGISTRY_NAME del proyecto con el valor del resultado de registryName.

La funcionalidad muestra cómo agregar Azure infraestructura al proyecto anfitrión de la aplicación, incluso si el servicio Azure no se expone directamente como una integración de .NET Aspire. Además, muestra cómo canalizar la salida del Azure Container Registry hacia el entorno de un proyecto dependiente.

Ten en cuenta el archivo Bicep resultante:

@description('The location for the resource(s) to be deployed.')
param location string = resourceGroup().location

resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
  name: take('acr${uniqueString(resourceGroup().id)}', 50)
  location: location
  sku: {
    name: 'Standard'
  }
}

output registryName string = acr.name

El archivo Bicep refleja la configuración deseada de Azure Container Registry, tal como se define en la API de AddAzureInfrastructure.

Uso de plantillas personalizadas de Bicep

Cuando tenga como destino Azure como proveedor de nube deseado, puede usar Bicep para definir la infraestructura como código. Tiene como objetivo simplificar drásticamente la experiencia de creación con una sintaxis más limpia y una mejor compatibilidad con la modularidad y la reutilización de código.

Aunque .NET.NET Aspire proporciona un conjunto de plantillas de Bicep precompiladas, puede haber ocasiones en las que quiera personalizar las plantillas o crear las suyas propias. En esta sección se explican los conceptos y las API correspondientes que puede usar para personalizar las plantillas de Bicep.

Importante

Esta sección no está pensada para enseñarte Bicep, sino para proporcionar una guía sobre cómo crear plantillas personalizadas de Bicep para su uso con .NET.NET Aspire.

Como parte de la historia de implementación de Azure para .NET Aspire, el Azure Developer CLI (azd) ofrece una comprensión de su proyecto .NET Aspire y la capacidad para implementarlo en Azure. La CLI de azd usa las plantillas de Bicep para implementar la aplicación en Azure.

Instalación de Aspire.Hosting.Azure paquete

Cuando quieres hacer referencia a archivos de Bicep, es posible que no estés usando ninguna de las integraciones de hospedaje Azure. En este caso, aún puede hacer referencia a archivos Bicep instalando el paquete Aspire.Hosting.Azure. Este paquete proporciona las API necesarias para hacer referencia a archivos de Bicep y personalizar los recursos de Azure.

Propina

Si usa cualquiera de las Azure integraciones de hospedaje, no es necesario instalar el paquete de Aspire.Hosting.Azure, ya que es una dependencia transitiva.

Para usar cualquiera de estas funcionalidades, el paquete NuGet 📦Aspire.Hosting.Azure debe estar instalado.

dotnet add package Aspire.Hosting.Azure

Para obtener más información, consulte dotnet add package o Manage package dependencies in .NET applications.

Qué esperar de los ejemplos

En todos los ejemplos de esta sección, se asume que estás usando el espacio de nombres Aspire.Hosting.Azure. Además, en los ejemplos se supone que tiene una instancia de IDistributedApplicationBuilder:

using Aspire.Hosting.Azure;

var builder = DistributedApplication.CreateBuilder(args);

// Examples go here...

builder.Build().Run();

De forma predeterminada, cuando se llama a cualquiera de las API relacionadas con Bicep, también se realiza una llamada a AddAzureProvisioning que agrega compatibilidad para generar recursos de Azure dinámicamente durante el inicio de la aplicación. Para obtener más información, consulte Aprovisionamiento Local y Azure.Provisioning.

Archivos de referencia de Bicep

Imagine que tiene una plantilla de Bicep en un archivo denominado storage.bicep que aprovisiona una Cuenta de Almacenamiento Azure:

param location string = resourceGroup().location
param storageAccountName string = 'toylaunch${uniqueString(resourceGroup().id)}'

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}

Para agregar una referencia al archivo de Bicep en el disco, llame al método AddBicepTemplate. Tenga en cuenta el ejemplo siguiente:

builder.AddBicepTemplate(
    name: "storage",
    bicepFile: "../infra/storage.bicep");

El código anterior agrega una referencia a un archivo de Bicep ubicado en ../infra/storage.bicep. Las rutas de acceso de archivo deben ser relativas al proyecto de hospedaje de la aplicación. Esta referencia da como resultado que se agregue un AzureBicepResource a la colección de recursos de la aplicación con el nombre "storage" y la API devuelve una instancia de IResourceBuilder<AzureBicepResource> que se puede usar para personalizar aún más el recurso.

Referencia en línea de Bicep

Aunque tener un archivo de Bicep en el disco es el escenario más común, también puede agregar plantillas de Bicep en línea. Las plantillas insertadas pueden ser útiles cuando se desea definir una plantilla en el código o cuando se desea generar la plantilla de forma dinámica. Para agregar una plantilla de Bicep insertada, llame al método AddBicepTemplateString con la plantilla de Bicep como string. Tenga en cuenta el ejemplo siguiente:

builder.AddBicepTemplateString(
        name: "ai",
        bicepContent: """
        @description('That name is the name of our application.')
        param cognitiveServiceName string = 'CognitiveService-${uniqueString(resourceGroup().id)}'

        @description('Location for all resources.')
        param location string = resourceGroup().location

        @allowed([
          'S0'
        ])
        param sku string = 'S0'

        resource cognitiveService 'Microsoft.CognitiveServices/accounts@2021-10-01' = {
          name: cognitiveServiceName
          location: location
          sku: {
            name: sku
          }
          kind: 'CognitiveServices'
          properties: {
            apiProperties: {
              statisticsEnabled: false
            }
          }
        }
        """
    );

En este ejemplo, la plantilla de Bicep se define en línea como string y se agrega a la colección de recursos de la aplicación con el nombre "ai". En este ejemplo se aprovisiona un recurso de inteligencia artificial modelo Azure.

Pasar parámetros a plantillas de Bicep

Bicep admite la aceptación de parámetros, que se pueden usar para personalizar el comportamiento de la plantilla. Para pasar parámetros a una plantilla de Bicep desde .NET.NET Aspire, encadene llamadas al método WithParameter como se muestra en el ejemplo siguiente:

var region = builder.AddParameter("region");

builder.AddBicepTemplate("storage", "../infra/storage.bicep")
       .WithParameter("region", region)
       .WithParameter("storageName", "app-storage")
       .WithParameter("tags", ["latest","dev"]);

El código anterior:

  • Agrega un parámetro denominado "region" a la instancia de builder.
  • Agrega una referencia a un archivo de Bicep ubicado en ../infra/storage.bicep.
  • Pasa el parámetro "region" a la plantilla de Bicep, que se resuelve mediante la resolución estándar de parámetros.
  • Pasa el parámetro "storageName" a la plantilla de Bicep con un valor de codificado de forma codificada de forma dura.
  • Pasa el parámetro "tags" a la plantilla de Bicep con un array de cadenas.

Para obtener más información, vea Parámetros externos.

Parámetros conocidos

.NET .NET Aspire proporciona un conjunto de parámetros conocidos que se pueden pasar a plantillas de Bicep. Estos parámetros se usan para proporcionar información sobre la aplicación y el entorno a las plantillas de Bicep. Están disponibles los siguientes parámetros conocidos:

Campo Descripción Valor
AzureBicepResource.KnownParameters.KeyVaultName Nombre del recurso del almacén de claves que se usa para almacenar resultados secretos. "keyVaultName"
AzureBicepResource.KnownParameters.Location Ubicación del recurso. Esto es necesario para todos los recursos. "location"
AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId Identificador de recurso del área de trabajo de Log Analytics. "logAnalyticsWorkspaceId"
AzureBicepResource.KnownParameters.PrincipalId El identificador principal del usuario actual o de la identidad gestionada. "principalId"
AzureBicepResource.KnownParameters.PrincipalName Nombre principal del usuario actual o identidad administrada. "principalName"
AzureBicepResource.KnownParameters.PrincipalType El tipo principal del usuario actual o la identidad administrada. User o ServicePrincipal. "principalType"

Para usar un parámetro conocido, pase el nombre del parámetro al método WithParameter, como WithParameter(AzureBicepResource.KnownParameters.KeyVaultName). No se pasan valores para parámetros conocidos, ya que .NET.NET Aspire los resuelve por usted.

Considere un ejemplo en el que desea configurar un webhook de Azure Event Grid. Puede definir la plantilla de Bicep de la siguiente manera:

param topicName string
param webHookEndpoint string
param principalId string
param principalType string
param location string = resourceGroup().location

// The topic name must be unique because it's represented by a DNS entry. 
// must be between 3-50 characters and contain only values a-z, A-Z, 0-9, and "-".

resource topic 'Microsoft.EventGrid/topics@2023-12-15-preview' = {
  name: toLower(take('${topicName}${uniqueString(resourceGroup().id)}', 50))
  location: location

  resource eventSubscription 'eventSubscriptions' = {
    name: 'customSub'
    properties: {
      destination: {
        endpointType: 'WebHook'
        properties: {
          endpointUrl: webHookEndpoint
        }
      }
    }
  }
}

resource EventGridRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: guid(topic.id, principalId, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7'))
  scope: topic
  properties: {
    principalId: principalId
    principalType: principalType
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a91429-5739-47e2-a06b-3470a27159e7')
  }
}

output endpoint string = topic.properties.endpoint

Esta plantilla de Bicep define varios parámetros, incluidos los topicName, webHookEndpoint, principalId, principalTypey el locationopcional . Para pasar estos parámetros a la plantilla de Bicep, puede usar el siguiente fragmento de código:

var webHookApi = builder.AddProject<Projects.WebHook_Api>("webhook-api");

var webHookEndpointExpression = ReferenceExpression.Create(
        $"{webHookApi.GetEndpoint("https")}/hook");

builder.AddBicepTemplate("event-grid-webhook", "../infra/event-grid-webhook.bicep")
       .WithParameter("topicName", "events")
       .WithParameter(AzureBicepResource.KnownParameters.PrincipalId)
       .WithParameter(AzureBicepResource.KnownParameters.PrincipalType)
       .WithParameter("webHookEndpoint", () => webHookEndpointExpression);
  • El proyecto de webHookApi se agrega como referencia al builder.
  • Al parámetro topicName se le pasa un valor de nombre fijo.
  • El parámetro webHookEndpoint se pasa como una expresión que se resuelve a la URL desde el punto de conexión "https" de las referencias del proyecto api con la ruta /hook.
  • Los parámetros principalId y principalType se pasan como parámetros conocidos.

Los parámetros conocidos se basan en convenciones y no deben ir acompañados de un valor correspondiente cuando se pasan mediante la API de WithParameter. Los parámetros conocidos simplifican algunas funcionalidades comunes, como las asignaciones de roles , cuando se agregan a las plantillas de Bicep, como se muestra en el ejemplo anterior. Las asignaciones de roles son necesarias para que el webhook de Event Grid envíe eventos al punto de conexión especificado. Para obtener más información, consulte asignación de roles del remitente de datos de Event Grid.

Obtención de resultados a partir de referencias de Bicep

Además de pasar parámetros a las plantillas de Bicep, también puede obtener resultados de las plantillas de Bicep. Considere la siguiente plantilla de Bicep, ya que define un output denominado endpoint:

param storageName string
param location string = resourceGroup().location

resource myStorageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
  name: storageName
  location: location
  kind: 'StorageV2'
  sku:{
    name:'Standard_LRS'
    tier: 'Standard'
  }
  properties: {
    accessTier: 'Hot'
  }
}

output endpoint string = myStorageAccount.properties.primaryEndpoints.blob

Bicep define una salida denominada endpoint. Para obtener la salida de la plantilla de Bicep, llame al método GetOutput en una instancia de IResourceBuilder<AzureBicepResource> como se muestra en el siguiente fragmento de código de C#:

var storage = builder.AddBicepTemplate(
        name: "storage",
        bicepFile: "../infra/storage.bicep"
    );

var endpoint = storage.GetOutput("endpoint");

En este ejemplo, la salida de la plantilla de Bicep se recupera y almacena en una variable endpoint. Normalmente, pasaría esta salida como una variable de entorno a otro recurso que se basa en él. Por ejemplo, si tenía un proyecto de API mínima ASP.NET Core que dependía de este punto de conexión, podría pasar la salida como una variable de entorno al proyecto mediante el siguiente fragmento de código:

var storage = builder.AddBicepTemplate(
                name: "storage",
                bicepFile: "../infra/storage.bicep"
            );

var endpoint = storage.GetOutput("endpoint");

var apiService = builder.AddProject<Projects.AspireSample_ApiService>(
        name: "apiservice"
    )
    .WithEnvironment("STORAGE_ENDPOINT", endpoint);

Para obtener más información, consulte las salidas de Bicep en .

Obtener resultados secretos de referencias de Bicep

Es importante evitar la salida de secretos al trabajar con Bicep. Si una salida se considera un secreto , lo que significa que no debe exponerse en registros u otros lugares, puede tratarlo como tal. Esto se puede lograr almacenando el secreto en Azure Key Vault y haciendo referencia a él en la plantilla de Bicep. La integración de .NET Aspirede Azure proporciona un patrón para almacenar de forma segura las salidas de la plantilla de Bicep al permitir a los recursos usar el parámetro keyVaultName para almacenar secretos en Azure Key Vault.

Considere la siguiente plantilla de Bicep como ejemplo que ayuda a demostrar este concepto de protección de salidas secretas:

param databaseAccountName string
param keyVaultName string

param databases array = []

@description('Tags that will be applied to all resources')
param tags object = {}

param location string = resourceGroup().location

var resourceToken = uniqueString(resourceGroup().id)

resource cosmosDb 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' = {
    name: replace('${databaseAccountName}-${resourceToken}', '-', '')
    location: location
    kind: 'GlobalDocumentDB'
    tags: tags
    properties: {
        consistencyPolicy: { defaultConsistencyLevel: 'Session' }
        locations: [
            {
                locationName: location
                failoverPriority: 0
            }
        ]
        databaseAccountOfferType: 'Standard'
    }

    resource db 'sqlDatabases@2023-04-15' = [for name in databases: {
        name: '${name}'
        location: location
        tags: tags
        properties: {
            resource: {
                id: '${name}'
            }
        }
    }]
}

var primaryMasterKey = cosmosDb.listKeys(cosmosDb.apiVersion).primaryMasterKey

resource vault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
    name: keyVaultName

    resource secret 'secrets@2023-07-01' = {
        name: 'connectionString'
        properties: {
            value: 'AccountEndpoint=${cosmosDb.properties.documentEndpoint};AccountKey=${primaryMasterKey}'
        }
    }
}

La plantilla de Bicep anterior espera un parámetro keyVaultName, entre otros parámetros. A continuación, define un recurso de Azure Cosmos DB y guarda un secreto en Azure Key Vault, el cual se denomina connectionString y representa la cadena de conexión completa a la instancia de Cosmos DB. Para acceder a este valor de cadena de conexión secreta, puede usar el siguiente fragmento de código:

var cosmos = builder.AddBicepTemplate("cosmos", "../infra/cosmosdb.bicep")
    .WithParameter("databaseAccountName", "fallout-db")
    .WithParameter(AzureBicepResource.KnownParameters.KeyVaultName)
    .WithParameter("databases", ["vault-33", "vault-111"]);

var connectionString =
    cosmos.GetSecretOutput("connectionString");

builder.AddProject<Projects.WebHook_Api>("api")
    .WithEnvironment(
        "ConnectionStrings__cosmos",
        connectionString);

En el fragmento de código anterior, la plantilla de cosmos Bicep se agrega como referencia a la builder. La salida secreta connectionString se recupera de la plantilla de Bicep y se almacena en una variable. A continuación, se pasa el resultado secreto como una variable de entorno (ConnectionStrings__cosmos) al proyecto api. Esta variable de entorno se usa para conectarse a la instancia de Cosmos DB.

Cuando se implementa este recurso, el mecanismo de implementación subyacente automáticamente secretos de referencia de Azure Key Vault. Para garantizar el aislamiento de secretos, .NET.NET Aspire crea un Key Vault por origen.

Nota

En modo de de aprovisionamiento local, el secreto se extrae de Key Vault y lo establece en una variable de entorno. Para más información, consulte el aprovisionamiento local Azure.

Editorial

Al publicar su aplicación, el aprovisionamiento generado por Bicep Azure es utilizado por el Azure Developer CLI para crear los recursos Azure en su suscripción Azure. .NET .NET Aspire genera una manifiesto de publicación, que también es una parte fundamental del proceso de publicación. El Azure Developer CLI es una herramienta de línea de comandos que proporciona un conjunto de comandos para administrar Azure recursos.

Para obtener más información sobre la publicación e implementación, consulte Implementación de un proyecto de .NET Aspire en Azure Container Apps mediante la Azure Developer CLI (guía detallada).