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
.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:
-
Azure. Personalización de aprovisionamiento:
- Configurar infraestructura: personalice infraestructura de recursos Azure.
- Agregar Azure infraestructura: agregue manualmente Azure infraestructura al host de la aplicación.
-
Usar plantillas de Bicep personalizadas:
- Hacer referencia a archivos de Bicep: agregue una referencia a un archivo de Bicep en el disco.
- Referencia Bicep en línea: Agregar una plantilla Bicep en línea.
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, veaAzure.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:- Obtiene los recursos aprovisionables.
- Filtra a una sola StorageAccount.
- Asigna el parámetro
storage-sku
a la propiedad StorageAccount.Sku:- Una nueva instancia del StorageSku tiene asignada su propiedad
Name
a partir del resultado de la API de AsProvisioningParameter.
- Una nueva instancia del StorageSku tiene asignada su propiedad
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 destring
y un valor que corresponde al nombre del Azure Container Registry. - Agrega la salida a la variable
infra
.
- Crea una instancia de un ContainerRegistryService con el nombre
- 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 deregistryName
.
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 debuilder
. - 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
, principalType
y el location
opcional . 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 albuilder
. - 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 proyectoapi
con la ruta/hook
. - Los parámetros
principalId
yprincipalType
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).