Partager via


Vue d’ensemble des intégrations .NET AspireAzure

Azure est la plateforme cloud la plus populaire pour la création et le déploiement d’applications .NET. Le SDK Azure pour .NET permet de gérer et d’utiliser facilement les services Azure. .NET Aspire fournit un ensemble d’intégrations avec Azure services, où vous êtes libre d’ajouter de nouvelles ressources ou de vous connecter à des ressources existantes. Cet article décrit certains aspects courants de toutes les intégrations Azure dans .NET Aspire et vise à vous aider à comprendre comment les utiliser.

Ajouter une connexion à des ressources Azure existantes

.NET .NET Aspire permet de se connecter aux ressources existantes, y compris les ressources Azure. L’expression de chaînes de connexion est utile lorsque vous disposez de ressources Azure existantes que vous souhaitez utiliser dans votre application .NET Aspire. L’API AddConnectionString est utilisée avec le contexte d’exécution de l’hôte d’application pour ajouter de manière conditionnelle une chaîne de connexion au modèle d’application.

Note

Les chaînes de connexion sont utilisées pour représenter un large éventail d’informations de connexion, notamment les connexions de base de données, les répartiteurs de messages, les URI de point de terminaison et d’autres services. Dans .NET.NET Aspire nomenclature, le terme « chaîne de connexion » est utilisé pour représenter n’importe quel type d’informations de connexion.

Prenons l'exemple suivant où, en mode de publication , vous ajoutez une ressource de stockage Azure, tandis qu'en mode d'exécution , vous ajoutez une chaîne de connexion à un stockage Azure existant :

var builder = DistributedApplication.CreateBuilder(args);

var storage = builder.ExecutionContext.IsPublishMode
    ? builder.AddAzureStorage("storage")
    : builder.AddConnectionString("storage");

builder.AddProject<Projects.Api>("api")
       .WithReference(storage);

// After adding all resources, run the app...

Code précédent :

  • Crée une nouvelle instance builder.
  • Ajoute une ressource de stockage Azure nommée storage en mode « publier ».
  • Ajoute une chaîne de connexion à un stockage Azure existant nommé storage en mode « Exécuter ».
  • Ajoute un projet nommé api au générateur.
  • Le projet api fait référence à la ressource storage quel que soit le mode.

Le projet d’API consommant utilise les informations de chaîne de connexion sans connaître la façon dont l’hôte de l’application l’a configuré. En mode « publier », le code ajoute une nouvelle ressource de stockage Azure, qui serait reflétée dans le manifeste de déploiement en conséquence. En mode « Exécuter », la chaîne de connexion correspond à une valeur de configuration visible pour l’hôte de l’application. Il est supposé que toutes les attributions de rôles pour la ressource cible ont été configurées. Cela signifie que vous configurez probablement une variable d’environnement ou un secret utilisateur pour stocker la chaîne de connexion. La configuration est résolue à partir de la clé de configuration ConnectionStrings__storage (ou ConnectionStrings:storage). Ces valeurs de configuration peuvent être consultées lorsque l’application s’exécute. Pour plus d’informations, consultez les détails des ressources .

Ajouter des ressources Azure

Toutes les intégrations d’hébergement .NET AspireAzure exposent des ressources Azure et par convention sont ajoutées à l’aide d’API AddAzure*. Lorsque vous ajoutez ces ressources à votre hôte d’application .NET Aspire, elles représentent un service Azure. L’API AddAzure* retourne une IResourceBuilder<T>T est le type de ressource Azure. Ces interfaces IResourceBuilder<T> (générateur) fournissent une API Fluent qui vous permet de configurer la ressource Azure sous-jacente au sein du modèle d’application .

Expérience de développement classique

Lorsque votre hôte d’application .NET Aspire contient des ressources Azure et que vous l’exécutez localement ( de développement standard ou expérience de dotnet run), les ressources Azure sont approvisionnées dans votre abonnement Azure. Cela vous permet en tant que développeur de déboguer sur eux localement dans le contexte de votre hôte d’application.

.NET .NET Aspire vise à réduire les coûts par défaut en de base ou StandardStock Keeping Unit (SKU) pour ses intégrations Azure. Bien que ces valeurs par défaut sensibles soient fournies, vous pouvez personnaliser les ressources Azure en fonction de vos besoins. En outre, certaines intégrations prennent en charge émulateurs ou conteneurs, ce qui est utile pour le développement, les tests et le débogage locaux. Par défaut, lorsque vous exécutez votre application localement, les ressources Azure utilisent le service Azure réel. Toutefois, vous pouvez les configurer pour utiliser des émulateurs ou des conteneurs locaux, ce qui évite les coûts associés au service de Azure réel pendant le développement local.

Émulateurs locaux

Certains services Azure peuvent être exécutés localement dans les émulateurs. Actuellement, .NET Aspire prend en charge les émulateurs de Azure suivants :

Intégration de l’hébergement Description
Azure Cosmos DB Appelez AzureCosmosExtensions.RunAsEmulator sur le IResourceBuilder<AzureCosmosDBResource> pour configurer la ressource Cosmos DB pour qu’elle soit émulée avec l’API NoSQL.
Azure Event Hubs Appelez AzureEventHubsExtensions.RunAsEmulator sur le IResourceBuilder<AzureEventHubsResource> pour configurer la ressource Event Hubs pour qu’elle soit émulée.
Azure Stockage Appelez AzureStorageExtensions.RunAsEmulator sur le IResourceBuilder<AzureStorageResource> pour configurer la ressource de stockage pour qu’elle soit émulée avec Azurite.

Pour que vos ressources Azure utilisent les émulateurs locaux, chaînez un appel à la méthode RunAsEmulator sur le générateur de ressources Azure. Cette méthode configure la ressource Azure pour utiliser l’émulateur local au lieu du service Azure réel.

Important

Appeler une API RunAsEmulator disponible dans un générateur de ressources Azure n’affecte pas le manifeste de publication . Lorsque vous publiez votre application, le fichier Bicep généré reflète le service Azure réel, pas l’émulateur local.

Conteneurs locaux

Certains services Azure peuvent être exécutés localement dans des conteneurs. Pour exécuter un service Azure localement dans un conteneur, chaînez un appel à la méthode RunAsContainer sur le générateur de ressources Azure. Cette méthode configure la ressource Azure pour qu’elle s’exécute localement dans un conteneur au lieu du service Azure réel.

Actuellement, .NET Aspire prend en charge les services de Azure suivants en tant que conteneurs :

Intégration de l’hébergement Détails
Azure Cache for Redis Appelez AzureRedisExtensions.RunAsContainer sur le IResourceBuilder<AzureRedisCacheResource> pour le configurer pour qu’il s’exécute localement dans un conteneur, en fonction de l’image docker.io/library/redis.
Azure PostgreSQL Server flexible Appelez AzurePostgresExtensions.RunAsContainer sur le IResourceBuilder<AzurePostgresFlexibleServerResource> pour le configurer pour qu’il s’exécute localement dans un conteneur, en fonction de l’image docker.io/library/postgres.
Azure SQL Server Appelez AzureSqlExtensions.RunAsContainer sur le IResourceBuilder<AzureSqlServerResource> pour le configurer pour qu’il s’exécute localement dans un conteneur, en fonction de l’image mcr.microsoft.com/mssql/server.

Note

Comme les émulateurs, appeler RunAsContainer sur un générateur de ressources Azure n’aura pas d'impact sur le manifeste de publication . Lorsque vous publiez votre application, le fichier Bicep généré reflète le service Azure réel, plutôt que le conteneur local.

Comprendre les API d’intégration Azure

.NET .NET Aspirela force réside dans sa capacité à fournir une boucle interne de développeur incroyable. Les intégrations Azure ne sont pas différentes. Ils fournissent un ensemble d’API et de modèles communs qui sont partagés entre toutes les ressources Azure. Ces API et modèles sont conçus pour faciliter l’utilisation de ressources Azure de manière cohérente.

Dans la section précédente sur les conteneurs, vous avez vu comment exécuter des services Azure localement dans des conteneurs. Si vous connaissez .NET.NET Aspire, vous pouvez vous demander comment appeler AddAzureRedis("redis").RunAsContainer() pour obtenir un conteneur docker.io/library/redis local diffère de AddRedis("redis"), car ils entraînent tous les deux le même conteneur local.

La réponse est qu’il n’existe aucune différence lors de l’exécution locale. Toutefois, lorsqu’ils sont publiés, vous obtenez différentes ressources :

API Mode d’exécution Mode de publication
AddAzureRedis( »redis« ). RunAsContainer() Conteneur Redis local Azure Cache for Redis
AddRedis( »redis« ) Conteneur Redis local Application de conteneur Azure avec l'image Redis

Il en va de même pour les services SQL et PostgreSQL :

API Mode d’exécution Mode de publication
AddAzurePostgresFlexibleServer( »postgres« ). RunAsContainer() Conteneur PostgreSQL local Azure PostgreSQL Server flexible
AddPostgres( »postgres« ) Conteneur PostgreSQL local Application de conteneur Azure avec l'image PostgreSQL
AddAzureSqlServer(« sql »).RunAsContainer() Conteneur SQL Server local Azure SQL Server
AddSqlServer(« sql ») Conteneur SQL Server local Application de conteneur Azure avec l'image SQL Server

Pour plus d’informations sur la différence entre les modes d’exécution et de publication, consultez .NET.NET Aspire'hôte d’application : contexte d’exécution.

Infrastructure en tant que code

Le Kit de développement logiciel (SDK) Azure pour .NET fournit le 📦Azureet le package NuGet pour l'approvisionnement, ainsi qu'une suite de packages d’approvisionnement spécifiques au service Azure. Ces bibliothèques d’approvisionnement Azure facilitent la spécification déclarative de l’infrastructure Azure en mode natif dans .NET. Leurs API vous permettent d’écrire une infrastructure orientée objet en C#, ce qui aboutit à Bicep. Bicep est un langage spécifique au domaine (DSL) pour le déploiement de ressources Azure de manière déclarative.

Bien qu’il soit possible de provisionner Azure ressources manuellement, .NET Aspire simplifie le processus en fournissant un ensemble d’API pour exprimer des ressources Azure. Ces API sont disponibles en tant que méthodes d’extension dans .NET AspireAzure bibliothèques d’hébergement, en étendant l’interface IDistributedApplicationBuilder. Lorsque vous ajoutez les ressources Azure à l'hôte de l'application, elles ajoutent implicitement la fonctionnalité d'approvisionnement appropriée. En d’autres termes, vous n’avez pas besoin d’appeler directement des API d’approvisionnement.

Étant donné que .NET Aspire modélise les ressources Azure au sein des intégrations d’hébergement Azure, le SDK Azure est utilisé pour fournir ces ressources. Les fichiers Bicep générés définissent les ressources Azure nécessaires. Les fichiers Bicep générés sont générés en même temps que le fichier manifeste lorsque vous publiez votre application.

Il existe plusieurs façons d’influencer les fichiers Bicep générés :

Approvisionnement local et Azure.Provisioning

Pour éviter la confusion des termes et aider à désambiguïser le « provisionnement », il est important de comprendre la distinction entre le provisionnement local et le provisionnement Azure:

  • approvisionnement local :

    Par défaut, lorsque vous appelez l’une des API d’intégration d’hébergement Azure pour ajouter des ressources Azure, l’API AddAzureProvisioning(IDistributedApplicationBuilder) est appelée implicitement. Cette API inscrit des services dans le conteneur d’injection de dépendances (DI) utilisé pour approvisionner des ressources Azure lorsque l’hôte de l’application démarre. Ce concept est appelé approvisionnement local. Pour plus d'informations, consultez la référence de provisionnement local Azure.

  • Azure.Provisioning:

    Azure.Provisioning fait référence au package NuGet et est un ensemble de bibliothèques qui vous permettent d’utiliser C# pour générer Bicep. Les Azure des intégrations d’hébergement dans .NET Aspire utilisez ces bibliothèques sous les couvertures pour générer des fichiers Bicep qui définissent les ressources Azure dont vous avez besoin. Pour plus d’informations, consultez Azure.Provisioningde personnalisation.

Personnalisation Azure.Provisioning

Toutes les intégrations d’hébergement .NET AspireAzure exposent diverses ressources Azure, et elles sont toutes des sous-classes du type AzureProvisioningResource, qui hérite elle-même de l'AzureBicepResource. Cela permet aux extensions qui sont limitées de façon générique à ce type, permettant ainsi à une API fluide de personnaliser l’infrastructure à votre guise. Bien que .NET.NET Aspire fournit des valeurs par défaut, vous êtes libre d’influencer le Bicep généré à l’aide de ces API.

Configurer l’infrastructure

Quelle que soit la ressource Azure avec laquelle vous travaillez, pour configurer son infrastructure sous-jacente, vous chaînez un appel à la méthode d’extension ConfigureInfrastructure. Cette méthode vous permet de personnaliser l’infrastructure de la ressource Azure en passant un délégué configure de type Action<AzureResourceInfrastructure>. Le type AzureResourceInfrastructure est une sous-classe du Azure.Provisioning.Infrastructure. Ce type expose une surface d’aire d’API massive pour la configuration de l’infrastructure sous-jacente de la ressource Azure.

Prenons l’exemple suivant :

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

Code précédent :

  • Ajoute un paramètre nommé storage-sku.
  • Ajoute le stockage Azure avec l'API nommée AddAzureStoragestorage.
  • Chaîne un appel à ConfigureInfrastructure pour personnaliser l’infrastructure de stockage Azure :

Cela illustre le flux d’un paramètre externe dans l’infrastructure de stockage Azure, ce qui entraîne le fichier Bicep généré reflétant la configuration souhaitée.

Ajouter une infrastructure Azure

Tous les services Azure ne sont pas nécessairement présentés en tant qu'intégrations .NET Aspire. Bien qu'ils puissent être disponibles plus tard, vous pouvez toujours fournir des services disponibles dans les bibliothèques Azure.Provisioning.*. Imaginez un scénario dans lequel vous avez un service de travail responsable de la gestion d’un registre de conteneurs Azure. Imaginez maintenant qu’un projet hôte d’application dépend du package NuGet 📦Azure.Provisioning.ContainerRegistry.

Vous pouvez utiliser l’API AddAzureInfrastructure pour ajouter l’infrastructure Azure Container Registry à votre hôte d’application :

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

Code précédent :

  • Appelle AddAzureInfrastructure sous le nom de acr.
  • Fournit un délégué configureInfrastructure pour personnaliser l'infrastructure Azure du registre de conteneurs :
    • Instancie un ContainerRegistryService avec le nom acr et un SKU standard.
    • Ajoute le service Azure Container Registry à la variable infra.
    • Instancie un ProvisioningOutput avec le nom registryName, un type de stringet une valeur qui correspond au nom du registre de conteneurs Azure.
    • Ajoute la valeur de sortie à la variable infra.
  • Ajoute un projet nommé worker au générateur.
  • Enchaîne un appel à WithEnvironment pour affecter à la variable d’environnement ACR_REGISTRY_NAME du projet la valeur de la sortie registryName.

La fonctionnalité montre comment ajouter l'infrastructure Azure à votre projet d'application hôte, même si le service Azure n’est pas directement exposé en tant qu’intégration .NET Aspire. Il montre également comment transmettre la sortie du registre de conteneurs Azure dans l’environnement d’un projet dépendant.

Considérez le fichier Bicep résultant :

@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

Le fichier Bicep reflète la configuration souhaitée du registre de conteneurs Azure, tel que défini par l’API AddAzureInfrastructure.

Utiliser des modèles Bicep personnalisés

Lorsque vous ciblez Azure en tant que fournisseur de cloud souhaité, vous pouvez utiliser Bicep pour définir votre infrastructure en tant que code. Il vise à simplifier considérablement l’expérience de création avec une syntaxe plus propre et une meilleure prise en charge de la modularité et de la réutilisation du code.

Bien que .NET.NET Aspire fournit un ensemble de modèles Bicep prédéfinis, il peut arriver que vous souhaitiez personnaliser les modèles ou créer vos propres modèles. Cette section explique les concepts et les API correspondantes que vous pouvez utiliser pour personnaliser les modèles Bicep.

Important

Cette section n’est pas destinée à vous apprendre à Bicep, mais plutôt à fournir des conseils sur la création de modèles Bicep personnalisés à utiliser avec .NET.NET Aspire.

Dans le cadre du récit de déploiement de Azure pour .NET Aspire, le Azure Developer CLI (azd) fournit une compréhension de votre projet de .NET Aspire et la possibilité de le déployer sur Azure. L’interface CLI azd utilise les modèles Bicep pour déployer l’application sur Azure.

Installez le paquet Aspire.Hosting.Azure

Lorsque vous souhaitez référencer des fichiers Bicep, il est possible que vous n’utilisiez aucune des intégrations d’hébergement de Azure. Dans ce cas, vous pouvez toujours référencer des fichiers Bicep en installant le package Aspire.Hosting.Azure. Ce package fournit les API nécessaires pour référencer les fichiers Bicep et personnaliser les ressources Azure.

Pourboire

Si vous utilisez l’une des intégrations d’hébergement Azure, vous n’avez pas besoin d’installer le package Aspire.Hosting.Azure, car il s’agit d’une dépendance transitive.

Pour utiliser l’une de ces fonctionnalités, le package NuGet 📦Aspire.Hosting.Azure doit être installé :

dotnet add package Aspire.Hosting.Azure

Pour plus d’informations, consultez dotnet add package ou Manage package dependencies in .NET applications.

Ce qu’il faut attendre des exemples

Tous les exemples de cette section supposent que vous utilisez l’espace de noms Aspire.Hosting.Azure. En outre, les exemples supposent que vous disposez d’une instance de IDistributedApplicationBuilder :

using Aspire.Hosting.Azure;

var builder = DistributedApplication.CreateBuilder(args);

// Examples go here...

builder.Build().Run();

Par défaut, lorsque vous appelez l’une des API liées à Bicep, un appel est également effectué pour AddAzureProvisioning qui ajoute la prise en charge de la génération dynamique de ressources Azure pendant le démarrage de l’application. Pour plus d’informations, consultez provisionnement local et Azure.Provisioning.

Référencer les fichiers Bicep

Imaginez que vous disposez d’un modèle Bicep dans un fichier nommé storage.bicep qui provisionne un compte de stockage 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'
  }
}

Pour ajouter une référence au fichier Bicep sur le disque, appelez la méthode AddBicepTemplate. Prenons l’exemple suivant :

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

Le code précédent ajoute une référence à un fichier Bicep situé à ../infra/storage.bicep. Les chemins d’accès aux fichiers doivent être relatifs au projet de l’hôte de l’application . Cette référence entraîne l’ajout d’une AzureBicepResource à la collection de ressources de l’application avec le nom "storage", et l’API retourne une instance IResourceBuilder<AzureBicepResource> qui peut être utilisée pour personnaliser davantage la ressource.

Référencer Bicep en ligne

Bien qu'avoir un fichier Bicep sur disque soit le scénario le plus courant, vous pouvez également ajouter des modèles Bicep en ligne. Les modèles inline peuvent être utiles lorsque vous souhaitez définir un modèle dans le code ou lorsque vous souhaitez générer le modèle de manière dynamique. Pour ajouter un modèle Bicep inline, appelez la méthode AddBicepTemplateString avec le modèle Bicep en tant que string. Prenons l’exemple suivant :

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

Dans cet exemple, le modèle Bicep est défini en tant que string inline et ajouté à la collection de ressources de l’application avec le nom "ai". Cet exemple provisionne une ressource d'intelligence artificielle Azure.

Passer des paramètres aux modèles Bicep

Bicep prend en charge l’acceptation des paramètres, qui peuvent être utilisés pour personnaliser le comportement du modèle. Pour passer des paramètres à un modèle Bicep à partir de .NET.NET Aspire, chaînez des appels à la méthode WithParameter, comme indiqué dans l’exemple suivant :

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

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

Code précédent :

  • Ajoute un paramètre nommé "region" à l’instance de builder.
  • Ajoute une référence à un fichier Bicep situé à ../infra/storage.bicep.
  • Transmet le paramètre "region" au modèle Bicep, qui est résolu à l’aide de la résolution des paramètres standard.
  • Transmet le paramètre au modèle Bicep avec une valeur fixe .
  • Transmet le paramètre "tags" au modèle Bicep avec un tableau de chaînes.

Pour plus d’informations, consultez paramètres externes.

Paramètres connus

.NET .NET Aspire fournit un ensemble de paramètres connus qui peuvent être passés aux modèles Bicep. Ces paramètres sont utilisés pour fournir des informations sur l’application et l’environnement aux modèles Bicep. Les paramètres connus suivants sont disponibles :

Champ Description Valeur
AzureBicepResource.KnownParameters.KeyVaultName Le nom de la ressource du Key Vault utilisée pour stocker les résultats secrets. "keyVaultName"
AzureBicepResource.KnownParameters.Location Emplacement de la ressource. Cette opération est requise pour toutes les ressources. "location"
AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId ID de ressource de l'espace de travail de Log Analytics. "logAnalyticsWorkspaceId"
AzureBicepResource.KnownParameters.PrincipalId ID principal de l’utilisateur actuel ou de l’identité managée. "principalId"
AzureBicepResource.KnownParameters.PrincipalName Nom principal de l’utilisateur actuel ou de l’identité managée. "principalName"
AzureBicepResource.KnownParameters.PrincipalType Type principal de l’utilisateur actuel ou de l’identité managée. User ou ServicePrincipal. "principalType"

Pour utiliser un paramètre connu, passez le nom du paramètre à la méthode WithParameter, par exemple WithParameter(AzureBicepResource.KnownParameters.KeyVaultName). Vous ne transmettez pas de valeurs pour les paramètres connus, car .NET.NET Aspire les résout en votre nom.

Prenons un exemple dans lequel vous souhaitez configurer un webhook Event Grid Azure. Vous pouvez définir le modèle Bicep comme suit :

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

Ce modèle Bicep définit plusieurs paramètres, notamment les topicName, les webHookEndpoint, les principalId, les principalTypeet les locationfacultatifs. Pour passer ces paramètres au modèle Bicep, vous pouvez utiliser l’extrait de code suivant :

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);
  • Le projet webHookApi est ajouté comme référence au builder.
  • Le paramètre topicName reçoit une valeur de nom codée en dur.
  • Le paramètre webHookEndpoint est passé en tant qu’expression qui se résout à l’URL à partir du point de terminaison « https » du projet api avec l’itinéraire /hook.
  • Les paramètres principalId et principalType sont passés en tant que paramètres connus.

Les paramètres connus sont basés sur des conventions et ne doivent pas être accompagnés d’une valeur correspondante lors de l’utilisation de l’API WithParameter. Les paramètres connus simplifient certaines fonctionnalités courantes, telles que les attributions de rôles , lorsqu’elles sont ajoutées aux modèles Bicep, comme illustré dans l’exemple précédent. Les attributions de rôles sont requises pour que le webhook Event Grid envoie des événements au point de terminaison spécifié. Pour plus d’informations, consultez attribution de rôle Expéditeur de données Event Grid.

Obtenez les résultats des références Bicep

En plus de passer des paramètres à des modèles Bicep, vous pouvez également obtenir des sorties à partir des modèles Bicep. Considérez le modèle Bicep suivant, car il définit une output nommée 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

Le Bicep définit une sortie nommée endpoint. Pour obtenir la sortie du modèle Bicep, appelez la méthode GetOutput sur une instance IResourceBuilder<AzureBicepResource>, comme illustré dans l’extrait de code C# suivant :

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

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

Dans cet exemple, la sortie du modèle Bicep est récupérée et stockée dans une variable endpoint. En règle générale, vous transmettez cette sortie en tant que variable d’environnement à une autre ressource qui s’appuie dessus. Par exemple, si vous aviez un projet d’API minimal ASP.NET Core qui dépendait de ce point de terminaison, vous pouvez transmettre la sortie en tant que variable d’environnement au projet à l’aide de l’extrait de code suivant :

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

Pour plus d'informations, consultez les sorties de Bicep .

Obtenez des sorties secrètes à partir des références de Bicep

Il est essentiel de éviter les sorties pour les secrets lors de l’utilisation de Bicep. Si une sortie est considérée comme un secret , ce qui signifie qu’elle ne doit pas être exposée dans des logs ou d’autres endroits, vous pouvez la traiter comme telle. Pour ce faire, stockez le secret dans Azure Key Vault et référencez-le dans le modèle Bicep. L'intégration de .NET Aspireà Azure fournit un modèle permettant de stocker en toute sécurité les sorties du modèle Bicep, en autorisant les ressources à utiliser le paramètre keyVaultName pour stocker les secrets dans Azure Key Vault.

Prenons l’exemple de modèle Bicep suivant pour illustrer ce concept de sécurisation des sorties secrètes :

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}'
        }
    }
}

Le modèle Bicep précédent attend un paramètre keyVaultName, entre autres paramètres. Il définit ensuite une ressource Azure Cosmos DB et place un secret dans Azure Key Vault, nommé connectionString qui représente la chaîne de connexion complète à l’instance de Cosmos DB. Pour accéder à cette valeur de chaîne de connexion secrète, vous pouvez utiliser l’extrait de code suivant :

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

Dans l’extrait de code précédent, le modèle cosmos Bicep est ajouté comme référence au builder. La sortie secrète connectionString est récupérée depuis le modèle Bicep et stockée dans une variable. La sortie du secret est ensuite transmise au projet ConnectionStrings__cosmos en tant que variable d'environnement (api). Cette variable d’environnement est utilisée pour se connecter à l’instance Cosmos DB.

Lorsque cette ressource est déployée, le mécanisme de déploiement sous-jacent des secrets de référence à partir de Azure Key Vault. Pour garantir l’isolation des secrets, .NET.NET Aspire crée un coffre de clés par source.

Note

Dans mode d’approvisionnement local, le secret est extrait de Key Vault et le définit dans une variable d’environnement. Pour plus d'informations, consultez la référence de provisionnement local Azure.

Édition

Lorsque vous publiez votre application, le Azure provisionnement généré par Bicep est utilisé par le Azure Developer CLI pour créer les ressources Azure dans votre abonnement Azure. .NET .NET Aspire génère un manifeste de publication , qui fait également partie intégrante du processus de publication. Le Azure Developer CLI est un outil en ligne de commande qui fournit un ensemble de commandes pour gérer les ressources Azure.

Pour plus d’informations sur la publication et le déploiement, consultez Déployer un projet .NET Aspire pour Azure Container Apps à l’aide du Azure Developer CLI (guide détaillé).