Déployer un projet .NET Aspire sur Azure Container Apps à l’aide du Azure Developer CLI (guide détaillé)
Le Azure Developer CLI (azd
) a été étendu pour prendre en charge le déploiement de projets .NET.NET Aspire. Utilisez ce guide pour parcourir le processus de création et de déploiement d’un projet .NET Aspire pour Azure Container Apps à l’aide du Azure Developer CLI. Dans ce tutoriel, vous allez découvrir les concepts suivants :
- Découvrez comment l’intégration
azd
fonctionne avec des projets .NET.NET Aspire - Approvisionner et déployer des ressources sur Azure pour un projet de .NET Aspire à l’aide de
azd
- Générer l’infrastructure Bicep et d’autres fichiers de modèle à l’aide de
azd
Conditions préalables
Pour utiliser .NET.NET Aspire, vous avez besoin de l’installation locale suivante :
- .NET 8.0 ou .NET 9.0
- Un runtime de conteneur conforme à OCI, tel que :
- Docker Desktop ou Podman. Pour plus d’informations, consultez du runtime de conteneur.
- Un environnement de développement intégré (IDE) ou un éditeur de code, par exemple :
- Visual Studio 2022 version 17.9 ou ultérieure (facultatif)
-
Visual Studio Code (facultatif)
- C# Dev Kit: Extension (facultatif)
- JetBrains Rider avec .NET.NET Aspire plug-in (facultatif)
Pour plus d’informations, consultez .NET.NET Aspire de configuration et outils, et .NET.NET Aspire SDK.
Vous devrez également installer le Azure Developer CLIlocalement. Les options d’installation courantes sont les suivantes :
Comment fonctionne l'intégration Azure Developer CLI
Le flux de travail azd init
fournit une prise en charge personnalisée des projets .NET.NET Aspire. Le diagramme suivant illustre le fonctionnement conceptuel de ce flux et la façon dont les azd
et les .NET.NET Aspire sont intégrés :
- Lorsque
azd
cible un projet .NET.NET Aspire, il démarre AppHost avec une commande spéciale (dotnet run --project AppHost.csproj --output-path manifest.json --publisher manifest
), qui produit le fichier manifeste Aspire. - Le fichier manifeste est interrogé par la logique de sous-commande
azd provision
pour générer des fichiers Bicep en mémoire uniquement (par défaut). - Après avoir généré les fichiers Bicep, un déploiement est déclenché à l’aide des API ARM de Azureciblant l’abonnement et le groupe de ressources fournis précédemment.
- Une fois les ressources Azure sous-jacentes configurées, la logique de sous-commande
azd deploy
est exécutée qui utilise le même fichier manifeste Aspire. - Dans le cadre du déploiement,
azd
effectue un appel àdotnet publish
en utilisant la prise en charge intégrée de la publication de conteneurs de .NETpour générer des images de conteneur. - Une fois que
azd
a généré les images conteneurs, il les pousse vers le registre ACR créé pendant la phase d’approvisionnement. - Enfin, une fois l’image conteneur dans ACR,
azd
met à jour la ressource à l’aide d’ARM pour commencer à utiliser la nouvelle version de l’image conteneur.
Note
azd
vous permet également d'exporter le Bicep généré vers un dossier infra
de votre projet, pour en savoir plus dans la section Génération de Bicep à partir de .NET.NET Aspire modèle d’application section.
Approvisionner et déployer une application de démarrage .NET.NET Aspire
Les étapes décrites dans cette section montrent comment créer une application de démarrage .NET Aspire et gérer l’approvisionnement et le déploiement des ressources d’application pour Azure à l’aide de azd
.
Créer l’application de démarrage .NET.NET Aspire
Créez un projet .NET.NET Aspire à l’aide de la commande dotnet new
. Vous pouvez également créer le projet à l’aide de Visual Studio.
dotnet new aspire-starter --use-redis-cache -o AspireSample
cd AspireSample
dotnet run --project AspireSample.AppHost\AspireSample.AppHost.csproj
Les commandes précédentes créent un nouveau projet .NET.NET Aspire basé sur le modèle aspire-starter
, qui inclut une dépendance à le cache Redis. Il exécute le projet .NET.NET Aspire qui vérifie que tout fonctionne correctement.
Initialiser le modèle
Ouvrez une nouvelle fenêtre de terminal et effectuez
cd
dans le répertoire de projet AppHost de votre solution .NET.NET Aspire.Exécutez la commande
azd init
pour initialiser votre projet avecazd
, qui inspecte la structure de répertoires local et détermine le type d’application.azd init
Pour plus d’informations sur la commande
azd init
, consultez azd init.Sélectionnez Utiliser du code dans le répertoire actif lorsque
azd
vous invite à utiliser deux options d’initialisation d’application.? How do you want to initialize your app? [Use arrows to move, type to filter] > Use code in the current directory Select a template
Après avoir analysé le répertoire,
azd
vous invite à confirmer qu’il a trouvé le projet .NET.NET AspireAppHost approprié. Sélectionnez l’option Confirmer et continuer l'initialisation de mon application.Detected services: .NET (Aspire) Detected in: D:\source\repos\AspireSample\AspireSample.AppHost\AspireSample.AppHost.csproj azd will generate the files necessary to host your app on Azure using Azure Container Apps. ? Select an option [Use arrows to move, type to filter] > Confirm and continue initializing my app Cancel and exit
Entrez un nom d’environnement, utilisé pour nommer les ressources provisionnée dans Azure et gérer différents environnements tels que
dev
etprod
.Generating files to run your app on Azure: (✓) Done: Generating ./azure.yaml (✓) Done: Generating ./next-steps.md SUCCESS: Your app is ready for the cloud! You can provision and deploy your app to Azure by running the azd up command in this directory. For more information on configuring your app, see ./next-steps.md
azd
génère un certain nombre de fichiers et les place dans le répertoire de travail. Ces fichiers sont les suivants :
- azure.yaml: décrit les services de l’application, tels que .NET Aspire projet AppHost, et les mappe aux ressources Azure.
-
.azure/config.json: fichier de configuration qui informe
azd
quel est l’environnement actif actuel. - .azure/aspireazddev/.env: contient des remplacements spécifiques à l’environnement.
Le fichier azure.yaml contient le contenu suivant :
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
name: AspireSample
services:
app:
language: dotnet
project: .\AspireSample.AppHost\AspireSample.AppHost.csproj
host: containerapp
Nommage des ressources
Lorsque vous créez de nouvelles ressources Azure, il est important de respecter les exigences de nommage. Pour Azure Container Apps, le nom doit contenir 2 à 32 caractères et se composer de lettres minuscules, de chiffres et de traits d’union. Le nom doit commencer par une lettre et se terminer par un caractère alphanumérique.
Pour plus d’informations, consultez règles et restrictions d’affectation de noms pour les ressources Azure.
Déploiement initial
Pour déployer le projet .NET Aspire, authentifiez-vous auprès de Azure AD pour appeler les API de gestion des ressources Azure.
azd auth login
La commande précédente lance un navigateur pour authentifier la session de ligne de commande.
Une fois authentifié, exécutez la commande suivante à partir du répertoire de projet AppHost pour approvisionner et déployer l’application.
azd up
Important
Pour transférer des images de conteneur à l'Azure Container Registry (ACR), vous devez disposer d'un accès à
Microsoft.Authorization/roleAssignments/write
. Pour ce faire, vous pouvez activer un utilisateur administrateur sur le Registre. Ouvrez le portail Azure, accédez à la ressource ACR/ Paramètres/ Clés d’accès, puis cochez la case 'utilisateur administrateur. Pour plus d’informations, consultez Activer l’utilisateur administrateur.Lorsque vous y êtes invité, sélectionnez l’abonnement et l’emplacement où les ressources doivent être déployées. Une fois ces options sélectionnées, le projet .NET.NET Aspire sera déployé.
By default, a service can only be reached from inside the Azure Container Apps environment it is running in. Selecting a service here will also allow it to be reached from the Internet. ? Select which services to expose to the Internet webfrontend ? Select an Azure Subscription to use: 1. <YOUR SUBSCRIPTION> ? Select an Azure location to use: 1. <YOUR LOCATION> Packaging services (azd package) Provisioning Azure resources (azd provision) Provisioning Azure resources can take some time. Subscription: <YOUR SUBSCRIPTION> Location: <YOUR LOCATION> You can view detailed progress in the Azure Portal: <LINK TO DEPLOYMENT> (✓) Done: Resource group: <YOUR RESOURCE GROUP> (✓) Done: Container Registry: <ID> (✓) Done: Log Analytics workspace: <ID> (✓) Done: Container Apps Environment: <ID> SUCCESS: Your application was provisioned in Azure in 1 minute 13 seconds. You can view the resources created under the resource group <YOUR RESOURCE GROUP> in Azure Portal: <LINK TO RESOURCE GROUP OVERVIEW> Deploying services (azd deploy) (✓) Done: Deploying service apiservice - Endpoint: <YOUR UNIQUE apiservice APP>.azurecontainerapps.io/ (✓) Done: Deploying service webfrontend - Endpoint: <YOUR UNIQUE webfrontend APP>.azurecontainerapps.io/ Aspire Dashboard: <LINK TO DEPLOYED .NET ASPIRE DASHBOARD> SUCCESS: Your up workflow to provision and deploy to Azure completed in 3 minutes 50 seconds.
La dernière ligne de sortie de la commande
azd
est un lien vers le portail Azure qui affiche toutes les ressources Azure déployées :
Trois conteneurs sont déployés dans cette application :
-
webfrontend
: contient du code à partir du projet web dans le modèle de démarrage. -
apiservice
: contient du code à partir du projet de service d’API dans le modèle de démarrage. -
cache
: image conteneur Redis pour fournir un cache au serveur frontal.
Tout comme dans le développement local, la configuration des chaînes de connexion a été gérée automatiquement. Dans ce cas, azd
était responsable de l’interprétation du modèle d’application et de sa traduction en étapes de déploiement appropriées. Par exemple, considérez la chaîne de connexion et les variables de découverte de service qui sont injectées dans le conteneur webfrontend
afin qu’elles sachent comment se connecter au cache Redis et apiservice
.
Pour plus d’informations sur la façon dont les projets .NET.NET Aspire gèrent les paramètres de connexion et la découverte des services, consultez l’aperçu de l’orchestration dans .NET.NET Aspire.
Déployer des mises à jour d’application
Lorsque la commande azd up
est exécutée, les ressources de Azure sous-jacentes sont approvisionnées et une image conteneur est générée et déployée sur les applications conteneur hébergeant le projet .NET.NET Aspire. En règle générale, une fois le développement en cours et Azure ressources sont déployées, il n’est pas nécessaire de provisionner des ressources Azure chaque fois que le code est mis à jour, ce qui est particulièrement vrai pour la boucle interne du développeur.
Pour accélérer le déploiement des modifications de code, azd
prend en charge le déploiement des mises à jour de code dans l’image conteneur. Pour ce faire, utilisez la commande azd deploy
:
azd deploy
Deploying services (azd deploy)
(✓) Done: Deploying service apiservice
- Endpoint: <YOUR UNIQUE apiservice APP>.azurecontainerapps.io/
(✓) Done: Deploying service webfrontend
- Endpoint: <YOUR UNIQUE webfrontend APP>.azurecontainerapps.io/
Aspire Dashboard: <LINK TO DEPLOYED .NET ASPIRE DASHBOARD>
Il n’est pas nécessaire de déployer tous les services à chaque fois.
azd
comprend le modèle de projet .NET.NET Aspire, il est possible de déployer uniquement l’un des services spécifiés à l’aide de la commande suivante :
azd deploy webfrontend
Pour plus d’informations, consultez la référence Azure Developer CLI : azd deploy.
Déployer des mises à jour d’infrastructure
Chaque fois que la structure de dépendances au sein d’un projet .NET.NET Aspire change, azd
devez réapprovisionnement des ressources Azure sous-jacentes. La commande azd provision
est utilisée pour appliquer ces modifications à l’infrastructure.
Pour voir cela en action, mettez à jour le fichier Program.cs dans le projet AppHost en procédant comme suit :
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
// Add the locations database.
var locationsdb = builder.AddPostgres("db").AddDatabase("locations");
// Add the locations database reference to the API service.
var apiservice = builder.AddProject<Projects.AspireSample_ApiService>("apiservice")
.WithReference(locationsdb);
builder.AddProject<Projects.AspireSample_Web>("webfrontend")
.WithReference(cache)
.WithReference(apiservice);
builder.Build().Run();
Enregistrez le fichier et émettez la commande suivante :
azd provision
La commande azd provision
met à jour l’infrastructure en créant une application conteneur pour héberger la base de données Postgres. La commande azd provision
n’a pas mis à jour les chaînes de connexion pour le conteneur apiservice
. Pour que les chaînes de connexion soient mises à jour pour pointer vers la base de données Postgres nouvellement provisionnée, la commande azd deploy
doit être appelée à nouveau. En cas de doute, utilisez azd up
pour approvisionner et déployer.
Nettoyer les ressources
N’oubliez pas de nettoyer les ressources Azure que vous avez créées pendant cette procédure pas à pas. Étant donné que « azd » connaît le groupe de ressources dans lequel il a créé les ressources, il peut être utilisé pour arrêter l'environnement à l'aide de la commande suivante :
azd down
La commande précédente peut prendre un certain temps pour s’exécuter, mais une fois le groupe de ressources terminé et toutes ses ressources doivent être supprimées.
Deleting all resources and deployed code on Azure (azd down)
Local application code is not deleted when running 'azd down'.
Resource group(s) to be deleted:
• <YOUR RESOURCE GROUP>: <LINK TO RESOURCE GROUP OVERVIEW>
? Total resources to delete: 7, are you sure you want to continue? Yes
Deleting your resources can take some time.
(✓) Done: Deleting resource group: <YOUR RESOURCE GROUP>
SUCCESS: Your application was removed from Azure in 9 minutes 59 seconds.
Générer Bicep à partir d’un modèle de projet .NET.NET Aspire
Bien que les équipes de développement soient libres d’utiliser des commandes azd up
(ou azd provision
et azd deploy
) pour leurs déploiements à des fins de développement et de production, certaines équipes peuvent choisir de générer des fichiers Bicep qu’ils peuvent examiner et gérer dans le cadre du contrôle de version (cela permet également à ces fichiers Bicep d’être référencés dans le cadre d’un déploiement plus complexe Azure plus volumineux).
azd
inclut la possibilité de générer le Bicep qu’il utilise pour l’approvisionnement via la commande suivante :
azd config set alpha.infraSynth on
azd infra synth
Une fois cette commande exécutée dans l’exemple de modèle de démarrage utilisé dans ce guide, les fichiers suivants sont créés dans le répertoire de projet AppHost :
- infra/main.bicep: représente le point d’entrée principal du déploiement.
- infra/main.parameters.json: utilisé comme paramètres pour Bicep principal (mappe aux variables d’environnement définies dans .azure dossier).
- infra/resources.bicep: définit les ressources Azure requises pour prendre en charge le modèle de projet .NET Aspire.
-
AspireSample.Web/manifests/containerApp.tmpl.yaml: définition de l’application conteneur pour
webfrontend
. -
AspireSample.ApiService/manifests/containerApp.tmpl.yaml: définition de l’application conteneur pour
apiservice
.
Le fichier infra\resources.bicep ne contient aucune définition des applications conteneur elles-mêmes (à l’exception des applications conteneur qui sont des dépendances telles que Redis et Postgres) :
@description('The location used for all deployed resources')
param location string = resourceGroup().location
@description('Tags that will be applied to all resources')
param tags object = {}
var resourceToken = uniqueString(resourceGroup().id)
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: 'mi-${resourceToken}'
location: location
tags: tags
}
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
name: replace('acr-${resourceToken}', '-', '')
location: location
sku: {
name: 'Basic'
}
tags: tags
}
resource caeMiRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(containerRegistry.id, managedIdentity.id, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d'))
scope: containerRegistry
properties: {
principalId: managedIdentity.properties.principalId
principalType: 'ServicePrincipal'
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
}
}
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
name: 'law-${resourceToken}'
location: location
properties: {
sku: {
name: 'PerGB2018'
}
}
tags: tags
}
resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = {
name: 'cae-${resourceToken}'
location: location
properties: {
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: logAnalyticsWorkspace.properties.customerId
sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey
}
}
}
tags: tags
}
resource cache 'Microsoft.App/containerApps@2023-05-02-preview' = {
name: 'cache'
location: location
properties: {
environmentId: containerAppEnvironment.id
configuration: {
service: {
type: 'redis'
}
}
template: {
containers: [
{
image: 'redis'
name: 'redis'
}
]
}
}
tags: union(tags, {'aspire-resource-name': 'cache'})
}
resource locations 'Microsoft.App/containerApps@2023-05-02-preview' = {
name: 'locations'
location: location
properties: {
environmentId: containerAppEnvironment.id
configuration: {
service: {
type: 'postgres'
}
}
template: {
containers: [
{
image: 'postgres'
name: 'postgres'
}
]
}
}
tags: union(tags, {'aspire-resource-name': 'locations'})
}
output MANAGED_IDENTITY_CLIENT_ID string = managedIdentity.properties.clientId
output AZURE_CONTAINER_REGISTRY_ENDPOINT string = containerRegistry.properties.loginServer
output AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID string = managedIdentity.id
output AZURE_CONTAINER_APPS_ENVIRONMENT_ID string = containerAppEnvironment.id
output AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN string = containerAppEnvironment.properties.defaultDomain
Pour plus d’informations sur l’utilisation de Bicep pour automatiser les déploiements vers Azure consultez Qu’est-ce que Bicep ?
La définition des applications conteneur à partir des projets de service .NET est contenue dans les fichiers containerApp/tmpl.yaml dans le répertoire manifests
de chaque projet respectivement. Voici un exemple du projet webfrontend
:
location: {{ .Env.AZURE_LOCATION }}
identity:
type: UserAssigned
userAssignedIdentities:
? "{{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }}"
: {}
properties:
environmentId: {{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_ID }}
configuration:
activeRevisionsMode: single
ingress:
external: true
targetPort: 8080
transport: http
allowInsecure: false
registries:
- server: {{ .Env.AZURE_CONTAINER_REGISTRY_ENDPOINT }}
identity: {{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }}
template:
containers:
- image: {{ .Env.SERVICE_WEBFRONTEND_IMAGE_NAME }}
name: webfrontend
env:
- name: AZURE_CLIENT_ID
value: {{ .Env.MANAGED_IDENTITY_CLIENT_ID }}
- name: ConnectionStrings__cache
value: {{ connectionString "cache" }}
- name: OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES
value: "true"
- name: OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES
value: "true"
- name: services__apiservice__0
value: http://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
- name: services__apiservice__1
value: https://apiservice.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
tags:
azd-service-name: webfrontend
aspire-resource-name: webfrontend
Après avoir exécuté la commande azd infra synth
, lorsque azd provision
et azd deploy
sont appelés, ils utilisent Bicep et prennent en charge les fichiers générés.
Important
Si azd infra synth
est appelé à nouveau, il remplace les fichiers modifiés par des fichiers générés à nouveau et vous invite à confirmer avant de le faire.
Environnements isolés pour le débogage
Étant donné que azd
facilite l’approvisionnement de nouveaux environnements, il est possible que chaque membre de l’équipe dispose d’un environnement hébergé dans le cloud isolé pour le débogage du code dans un paramètre qui correspond étroitement à la production. Lorsque vous effectuez cette opération, chaque membre de l’équipe doit créer son propre environnement à l’aide de la commande suivante :
azd env new
Cela demandera de nouveau à l'utilisateur les informations concernant l'abonnement et le groupe de ressources, et les appels suivants, azd up
, azd provision
et azd deploy
, utiliseront par défaut ce nouvel environnement. Le commutateur --environment
peut être appliqué à ces commandes pour basculer entre les environnements.
Nettoyer les ressources
Exécutez la commande CLI Azure suivante pour supprimer le groupe de ressources lorsque vous n’avez plus besoin des ressources Azure que vous avez créées. La suppression du groupe de ressources supprime également les ressources contenues à l’intérieur de celui-ci.
az group delete --name <your-resource-group-name>
Pour plus d’informations, consultez Nettoyer les ressources dans Azure.