Déploiement de Orleans sur Azure Container Apps
Dans ce tutoriel, vous allez découvrir comment déployer un exemple d’application de panier Orleans sur Azure Container Apps. Ce tutoriel étend les fonctionnalités de l’exemple d’application de panier Orleans, introduit dans Déploiement de Orleans sur Azure App Service. L’exemple d’application ajoute l’authentification B2C (entreprise-client) Azure Active Directory (AAD), et est déployé sur Azure Container Apps.
Vous allez découvrir comment effectuer un déploiement en utilisant GitHub Actions, les interfaces .NET CLI et Azure CLI ainsi qu’Azure Bicep. De plus, vous allez apprendre à configurer l’entrée HTTP de Container Apps.
Dans ce tutoriel, vous allez apprendre à :
- Déploiement d’une application Orleans sur Azure Container Apps
- Automatiser le déploiement à l’aide de GitHub Actions et d’Azure Bicep
- Configurer l’entrée HTTP
Prérequis
- Un compte GitHub
- Lire une présentation de Orleans
- Le kit SDK .NET 6
- Azure CLI
- Un IDE (environnement de développement intégré) .NET
- N’hésitez pas à utiliser Visual Studio ou Visual Studio Code
Exécutez l’application localement.
Pour exécuter l’application localement, dupliquez (fork) le référentiel Exemples Azure : panier Orleans sur Azure Container Apps, puis clonez-le sur votre ordinateur local. Une fois le clonage effectué, ouvrez la solution dans l’IDE de votre choix. Si vous utilisez Visual Studio, cliquez avec le bouton droit sur le projet Orleans.ShoppingCart.Silo, sélectionnez Définir en tant que projet de démarrage, puis exécutez l’application. Sinon, vous pouvez exécuter l’application à l’aide de la commande .NET CLI suivante :
dotnet run --project Silo\Orleans.ShoppingCart.Silo.csproj
Pour plus d’informations, consultez dotnet run. Une fois l’application en cours d’exécution, une page de destination décrivant les fonctionnalités de l’application s’affiche. Dans le coin supérieur droit, vous pouvez voir un bouton de connexion. Vous pouvez vous inscrire pour obtenir un compte, ou vous connecter si vous disposez déjà d’un compte. Une fois connecté, vous pouvez naviguer et tester librement ses fonctionnalités. Toutes les fonctionnalités de l’application, quand elle s’exécute localement, reposent sur la persistance en mémoire et le clustering local. De plus, l’application utilise le package NuGet Bogus pour générer des produits fictifs. Arrêtez l’application en sélectionnant l’option Arrêter le débogage dans Visual Studio, ou en appuyant sur Ctrl+C dans l’interface .NET CLI.
AAD B2C
Bien que l’enseignement des concepts liés à l’authentification dépasse le cadre de ce tutoriel, vous pouvez apprendre à créer un locataire Azure Active Directory B2C, et inscrire une application web pour le consommer. Dans le cas de cet exemple d’application de panier, l’URL résultante de l’application déployée sur Container Apps doit être inscrite auprès du locataire B2C. Pour plus d’informations, consultez Authentification et autorisation ASP.NET Core Blazor.
Important
Une fois votre application déployée sur Container Apps, vous devez inscrire son URL auprès du locataire B2C. Dans la plupart des scénarios de production, vous n’avez besoin d’inscrire l’URL de l’application qu’une seule fois, car elle ne doit pas changer.
Pour mieux visualiser la façon dont l’application est isolée dans l’environnement Azure Container Apps, consultez le diagramme suivant :
Dans le diagramme précédent, tout le trafic entrant vers l’application est dirigé via une entrée HTTP sécurisée. L’environnement Azure Container Apps contient une instance d’application dont l’hôte ASP.NET Core expose les fonctionnalités d’application Blazor Server et Orleans.
Déployer sur Azure Container Apps
Pour déployer l’application sur Azure Container Apps, le dépôt utilise GitHub Actions. Pour que ce déploiement puisse avoir lieu, vous avez besoin de quelques ressources Azure, et vous devez configurer correctement le dépôt GitHub.
Avant de déployer l’application, vous devez créer un groupe de ressources Azure, ou choisir d’utiliser un groupe existant. Pour créer un groupe de ressources Azure, utilisez l’un des articles suivants :
Notez le nom du groupe de ressources que vous choisissez. Vous en aurez besoin plus tard pour déployer l’application.
Créer un principal du service
Pour automatiser le déploiement de l’application, vous devez créer un principal de service. Il s’agit d’un compte Microsoft qui dispose de l’autorisation nécessaire pour gérer les ressources Azure en votre nom.
az ad sp create-for-rbac --sdk-auth --role Contributor \
--name "<display-name>" --scopes /subscriptions/<your-subscription-id>
Les informations d’identification JSON créées ressemblent à ce qui suit, mais avec des valeurs réelles pour votre client, votre abonnement et votre locataire :
{
"clientId": "<your client id>",
"clientSecret": "<your client secret>",
"subscriptionId": "<your subscription id>",
"tenantId": "<your tenant id>",
"activeDirectoryEndpointUrl": "https://login.microsoftonline.com/",
"resourceManagerEndpointUrl": "https://brazilus.management.azure.com",
"activeDirectoryGraphResourceId": "https://graph.windows.net/",
"sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
"galleryEndpointUrl": "https://gallery.azure.com",
"managementEndpointUrl": "https://management.core.windows.net"
}
Copiez la sortie de la commande dans votre Presse-papiers, puis passez à l’étape suivante.
Créer un secret GitHub
GitHub fournit un mécanisme de création de secrets chiffrés. Les secrets que vous créez peuvent être utilisés dans les workflows GitHub Actions. Vous allez voir comment GitHub Actions peut être utilisé pour automatiser le déploiement de l’application, conjointement avec Azure Bicep.
Bicep est un langage dédié (DSL), qui utilise une syntaxe déclarative pour déployer les ressources Azure. Pour plus d’informations, consultez Qu’est-ce que Bicep. À l’aide de la sortie de l’étape Créer un principal de service, vous devez créer un secret GitHub nommé AZURE_CREDENTIALS
avec les informations d’identification au format JSON.
Dans le dépôt GitHub, sélectionnez Paramètres>Secrets>Créer un secret. Entrez le nom AZURE_CREDENTIALS
et collez les informations d’identification au format JSON de l’étape précédente dans le champ Valeur.
Pour plus d’informations, consultez GitHub : Secrets chiffrés.
Préparer le déploiement Azure
L’application doit être packagée pour le déploiement. Dans le projet Orleans.ShoppingCart.Silos
, nous définissons un élément Target
qui s’exécute après l’étape Publish
. Cela entraîne la compression du répertoire de publication dans un fichier silo.zip :
<Target Name="ZipPublishOutput" AfterTargets="Publish">
<Delete Files="$(ProjectDir)\..\silo.zip" />
<ZipDirectory SourceDirectory="$(PublishDir)" DestinationFile="$(ProjectDir)\..\silo.zip" />
</Target>
Il existe de nombreuses façons de déployer une application .NET sur Azure Container Apps. Dans ce tutoriel, vous allez utiliser GitHub Actions, Azure Bicep ainsi que les interfaces .NET CLI et Azure CLI. Prenons l’exemple du fichier ./github/workflows/deploy.yml situé à la racine du dépôt GitHub :
name: Deploy to Azure Container Apps
on:
push:
branches:
- main
env:
UNIQUE_APP_NAME: orleanscart
SILO_IMAGE_NAME: orleanscart-silo
AZURE_RESOURCE_GROUP_NAME: orleans-resourcegroup
AZURE_RESOURCE_GROUP_LOCATION: eastus
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET 6.0
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.x
- name: .NET publish shopping cart app
run: dotnet publish ./Silo/Orleans.ShoppingCart.Silo.csproj --configuration Release
- name: Login to Azure
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Flex ACR Bicep
run: |
az deployment group create \
--resource-group ${{ env.AZURE_RESOURCE_GROUP_NAME }} \
--template-file '.github/workflows/flex/acr.bicep' \
--parameters location=${{ env.AZURE_RESOURCE_GROUP_LOCATION }}
- name: Get ACR Login Server
run: |
ACR_NAME=$(az deployment group show -g ${{ env.AZURE_RESOURCE_GROUP_NAME }} -n acr \
--query properties.outputs.acrName.value | tr -d '"')
echo "ACR_NAME=$ACR_NAME" >> $GITHUB_ENV
ACR_LOGIN_SERVER=$(az deployment group show -g ${{ env.AZURE_RESOURCE_GROUP_NAME }} -n acr \
--query properties.outputs.acrLoginServer.value | tr -d '"')
echo "ACR_LOGIN_SERVER=$ACR_LOGIN_SERVER" >> $GITHUB_ENV
- name: Prepare Docker buildx
uses: docker/setup-buildx-action@v1
- name: Login to ACR
run: |
access_token=$(az account get-access-token --query accessToken -o tsv)
refresh_token=$(curl https://${{ env.ACR_LOGIN_SERVER }}/oauth2/exchange -v \
-d "grant_type=access_token&service=${{ env.ACR_LOGIN_SERVER }}&access_token=$access_token" | jq -r .refresh_token)
# The null GUID 0000... tells the container registry that this is an ACR refresh token during the login flow
docker login -u 00000000-0000-0000-0000-000000000000 \
--password-stdin ${{ env.ACR_LOGIN_SERVER }} <<< "$refresh_token"
- name: Build and push Silo image to registry
uses: docker/build-push-action@v2
with:
push: true
tags: ${{ env.ACR_LOGIN_SERVER }}/${{ env.SILO_IMAGE_NAME }}:${{ github.sha }}
file: Silo/Dockerfile
- name: Flex ACA Bicep
run: |
az deployment group create \
--resource-group ${{ env.AZURE_RESOURCE_GROUP_NAME }} \
--template-file '.github/workflows/flex/main.bicep' \
--parameters location=${{ env.AZURE_RESOURCE_GROUP_LOCATION }} \
appName=${{ env.UNIQUE_APP_NAME }} \
acrName=${{ env.ACR_NAME }} \
repositoryImage=${{ env.ACR_LOGIN_SERVER }}/${{ env.SILO_IMAGE_NAME }}:${{ github.sha }} \
--debug
- name: Get Container App URL
run: |
ACA_URL=$(az deployment group show -g ${{ env.AZURE_RESOURCE_GROUP_NAME }} \
-n main --query properties.outputs.acaUrl.value | tr -d '"')
echo $ACA_URL
- name: Logout of Azure
run: az logout
Le workflow GitHub précédent va :
- Publier l’application de panier sous forme de fichier zip, à l’aide de la commande dotnet publish.
- Connectez-vous à Azure à l’aide des informations d’identification de l’étape Créer un principal de service.
- Évaluer le fichier acr.bicep et démarrer un groupe de déploiement à l’aide de la commande az deployment group create.
- Obtenir le serveur de connexion ACR (Azure Container Registry) à partir du groupe de déploiement.
- Se connecter à ACR à l’aide du secret
AZURE_CREDENTIALS
des dépôts. - Générer et publier l’image de silo sur l’ACR.
- Évaluer le fichier main.bicep et démarrer un groupe de déploiement à l’aide de la commande az deployment group create.
- Déployer le silo
- Se déconnecter d’Azure.
Le workflow est déclenché par une poussée vers la branche main. Pour plus d’informations, consultez GitHub Actions et .NET.
Conseil
Si vous rencontrez des problèmes au moment de l’exécution du workflow, vous devrez peut-être vérifier que tous les espaces de noms de fournisseurs nécessaires sont inscrits pour le principal de service. Les espaces de noms de fournisseurs suivants sont obligatoires :
Microsoft.App
Microsoft.ContainerRegistry
Microsoft.Insights
Microsoft.OperationalInsights
Microsoft.Storage
Pour plus d’informations, consultez Résoudre les erreurs d’inscription du fournisseur de ressources.
Azure impose des restrictions et des conventions de nommage pour les ressources. Vous devez mettre à jour les valeurs du fichier deploy.yml pour ce qui suit :
UNIQUE_APP_NAME
SILO_IMAGE_NAME
AZURE_RESOURCE_GROUP_NAME
AZURE_RESOURCE_GROUP_LOCATION
Affectez à ces valeurs le nom unique de votre application ainsi que le nom et l’emplacement de votre groupe de ressources Azure.
Pour plus d’informations, consultez les règles de nommage et les restrictions.
Explorer les modèles Bicep
Quand la commande az deployment group create
est exécutée, elle évalue une référence de fichier .bicep donnée. Ce fichier contient des informations déclaratives qui détaillent les ressources Azure à déployer. Vous pouvez vous représenter cette étape comme le provisionnement de toutes les ressources du déploiement.
Important
Si vous utilisez Visual Studio Code, l’expérience de création Bicep est améliorée quand vous utilisez l’extension Bicep.
Le premier fichier Bicep évalué est le fichier acr.bicep. Ce fichier contient les détails des ressources du serveur de connexion ACR (Azure Container Registry) :
param location string = resourceGroup().location
resource acr 'Microsoft.ContainerRegistry/registries@2021-09-01' = {
name: toLower('${uniqueString(resourceGroup().id)}acr')
location: location
sku: {
name: 'Basic'
}
properties: {
adminUserEnabled: true
}
}
output acrLoginServer string = acr.properties.loginServer
output acrName string = acr.name
Ce fichier Bicep génère en sortie le serveur de connexion ACR et le nom correspondant. Le prochain fichier Bicep rencontré contient plusieurs resource
. Prenons l’exemple du fichier main.bicep, constitué principalement de délégations de définitions de module
:
param appName string
param acrName string
param repositoryImage string
param location string = resourceGroup().location
resource acr 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = {
name: acrName
}
module env 'environment.bicep' = {
name: 'containerAppEnvironment'
params: {
location: location
operationalInsightsName: '${appName}-logs'
appInsightsName: '${appName}-insights'
}
}
var envVars = [
{
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
value: env.outputs.appInsightsInstrumentationKey
}
{
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: env.outputs.appInsightsConnectionString
}
{
name: 'ORLEANS_AZURE_STORAGE_CONNECTION_STRING'
value: storageModule.outputs.connectionString
}
{
name: 'ASPNETCORE_FORWARDEDHEADERS_ENABLED'
value: 'true'
}
]
module storageModule 'storage.bicep' = {
name: 'orleansStorageModule'
params: {
name: '${appName}storage'
location: location
}
}
module siloModule 'container-app.bicep' = {
name: 'orleansSiloModule'
params: {
appName: appName
location: location
containerAppEnvironmentId: env.outputs.id
repositoryImage: repositoryImage
registry: acr.properties.loginServer
registryPassword: acr.listCredentials().passwords[0].value
registryUsername: acr.listCredentials().username
envVars: envVars
}
}
output acaUrl string = siloModule.outputs.acaUrl
Fichier Bicep précédent :
- Référence une ressource ACR
existing
. Pour plus d’informations, consultez Azure Bicep : Ressources existantes. - Définit un
module env
, qui effectue une délégation au fichier de définition environment.bicep. - Définit un
module storageModule
, qui effectue une délégation au fichier de définition storage.bicep. - Déclare plusieurs
envVars
partagés utilisés par le module silo. - Définit un
module siloModule
, qui effectue une délégation au fichier de définition container-app.bicep. - Génère l’URL ACA (qui peut éventuellement être utilisée pour mettre à jour l’URI de redirection d’une inscription d’application AAD B2C).
Le fichier main.bicep effectue une délégation à plusieurs autres fichiers Bicep. Le premier est le fichier environment.bicep :
param operationalInsightsName string
param appInsightsName string
param location string
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
name: appInsightsName
location: location
kind: 'web'
properties: {
Application_Type: 'web'
WorkspaceResourceId: logs.id
}
}
resource logs 'Microsoft.OperationalInsights/workspaces@2021-06-01' = {
name: operationalInsightsName
location: location
properties: {
retentionInDays: 30
features: {
searchVersion: 1
}
sku: {
name: 'PerGB2018'
}
}
}
resource env 'Microsoft.App/managedEnvironments@2022-03-01' = {
name: '${resourceGroup().name}env'
location: location
properties: {
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: logs.properties.customerId
sharedKey: logs.listKeys().primarySharedKey
}
}
}
}
output id string = env.id
output appInsightsInstrumentationKey string = appInsights.properties.InstrumentationKey
output appInsightsConnectionString string = appInsights.properties.ConnectionString
Ce fichier Bicep définit les ressources Azure Log Analytics et Application Insights. La ressource appInsights
est de type web
et la ressource logs
est de type PerGB2018
. La ressource appInsights
et la ressource logs
sont toutes deux provisionnées à l’emplacement du groupe de ressources. La ressource appInsights
est liée à la ressource logs
via la propriété WorkspaceResourceId
. Il existe trois sorties définies dans ce fichier Bicep, utilisées plus tard par le module
de Container Apps. Examinons ensuite le fichier storage.bicep :
param name string
param location string
resource storage 'Microsoft.Storage/storageAccounts@2021-08-01' = {
name: name
location: location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
}
var key = listKeys(storage.name, storage.apiVersion).keys[0].value
var protocol = 'DefaultEndpointsProtocol=https'
var accountBits = 'AccountName=${storage.name};AccountKey=${key}'
var endpointSuffix = 'EndpointSuffix=${environment().suffixes.storage}'
output connectionString string = '${protocol};${accountBits};${endpointSuffix}'
Le fichier Bicep précédent définit ceci :
- Deux paramètres pour le nom du groupe de ressources et le nom de l’application.
- La définition
resource storage
pour le compte de stockage. - Un seul
output
, qui construit la chaîne de connexion pour le compte de stockage.
Le dernier fichier Bicep est le fichier container-app.bicep :
param appName string
param location string
param containerAppEnvironmentId string
param repositoryImage string = 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'
param envVars array = []
param registry string
param registryUsername string
@secure()
param registryPassword string
resource containerApp 'Microsoft.App/containerApps@2022-03-01' = {
name: appName
location: location
properties: {
managedEnvironmentId: containerAppEnvironmentId
configuration: {
activeRevisionsMode: 'multiple'
secrets: [
{
name: 'container-registry-password'
value: registryPassword
}
]
registries: [
{
server: registry
username: registryUsername
passwordSecretRef: 'container-registry-password'
}
]
ingress: {
external: true
targetPort: 80
}
}
template: {
revisionSuffix: uniqueString(repositoryImage, appName)
containers: [
{
image: repositoryImage
name: appName
env: envVars
}
]
scale: {
minReplicas: 1
maxReplicas: 1
}
}
}
}
output acaUrl string = containerApp.properties.configuration.ingress.fqdn
L’extension Visual Studio Code pour Bicep mentionnée ci-dessus comprend un visualiseur. Tous ces fichiers Bicep sont visualisés de la façon suivante :
Résumé
Quand vous mettez à jour le code source et que vous effectuez un push
des changements apportés à la branche main
du dépôt, le workflow deploy.yml s’exécute. Il provisionne les ressources Azure définies dans les fichiers Bicep et déploie l’application. Les révisions sont automatiquement inscrites dans votre registre de conteneurs Azure Container Registry.
En plus du visualiseur de l’extension Bicep, la page du groupe de ressources du portail Azure ressemble à l’exemple suivant après le provisionnement et le déploiement de l’application :