Je pars sur une application .NET (ASP.NET Core) dĂ©ployĂ©e sur Azure App Service, avec Azure DevOps pour le pipeline. Si ta stack est diffĂ©rente (conteneurs, Functions, AKS), l’approche reste la mĂȘme, seules les tĂąches de dĂ©ploiement changent.
Architecture
Visual Studio â Azure Repos (ou GitHub) â Azure Pipelines â Build + Tests â Artefact â Staging (slot) â Approbation â Swap vers Production â Application Insights
Ătape 1 : PrĂ©parer le projet dans Visual Studio
- Ouvre ta solution et ajoute un projet de tests (xUnit ou NUnit). Vérifie que tout passe dans Test Explorer.
- Ajoute un endpoint de santé, utile pour les smoke tests :
builder.Services.AddHealthChecks();// ...app.MapHealthChecks("/health"); - CrĂ©e le dĂ©pĂŽt Git : menu Git â Create Git Repository, puis choisis Azure DevOps ou GitHub et pousse le code.
Ătape 2 : CrĂ©er les ressources Azure
Avec Azure CLI (ou le portail) :
az loginaz group create -n rg-monapp -l canadaeastaz appservice plan create -n plan-monapp -g rg-monapp --sku S1az webapp create -n monapp-web -g rg-monapp -p plan-monapp --runtime "dotnet:8"az webapp deployment slot create -n monapp-web -g rg-monapp --slot staging
Points importants :
- Les slots de déploiement demandent un plan Standard (S1) ou supérieur.
- Adapte le nom
monapp-web, qui doit ĂȘtre unique mondialement. VĂ©rifie les runtimes disponibles avecaz webapp list-runtimes. - Ajoute Application Insights (créé avec le Web App ou sĂ©parĂ©ment) pour le monitoring.
Ătape 3 : Configurer Azure DevOps
- Crée un projet sur dev.azure.com.
- Project Settings â Service connections â New â Azure Resource Manager. Choisis l’authentification Workload identity federation (recommandĂ©e, sans secret Ă gĂ©rer) et limite la portĂ©e au groupe de ressources
rg-monapp. Nomme-lasc-azure-prod. - Pipelines â Environments : crĂ©e
stagingetproduction. - Sur
production, ajoute une Approval check (toi ou ton équipe).
à noter : les agents hébergés par Microsoft peuvent nécessiter une demande de parallélisme gratuit sur les nouvelles organisations. Vérifie ce point dans les paramÚtres de ton organisation si le pipeline reste en attente.
Ătape 4 : Le pipeline azure-pipelines.yml
à la racine du dépÎt :
trigger: branches: include: [main]pr: branches: include: [main]pool: vmImage: 'ubuntu-latest'variables: buildConfiguration: 'Release' azureSubscription: 'sc-azure-prod' webAppName: 'monapp-web' resourceGroup: 'rg-monapp'stages:# ---------- CI ----------- stage: Build jobs: - job: BuildTest steps: - task: UseDotNet@2 inputs: packageType: sdk version: '8.x' - task: DotNetCoreCLI@2 displayName: Restore inputs: command: restore projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: Build inputs: command: build projects: '**/*.csproj' arguments: '--configuration $(buildConfiguration) --no-restore' - task: DotNetCoreCLI@2 displayName: Tests unitaires inputs: command: test projects: '**/*Tests.csproj' arguments: '--configuration $(buildConfiguration) --no-build --collect:"XPlat Code Coverage"' - task: DotNetCoreCLI@2 displayName: Publish inputs: command: publish publishWebProjects: true arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)' zipAfterPublish: true - publish: $(Build.ArtifactStagingDirectory) artifact: drop# ---------- CD : Staging ----------- stage: DeployStaging dependsOn: Build condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) jobs: - deployment: Staging environment: staging strategy: runOnce: deploy: steps: - task: AzureWebApp@1 displayName: Déploiement dans le slot staging inputs: azureSubscription: $(azureSubscription) appType: webApp appName: $(webAppName) deployToSlotOrASE: true resourceGroupName: $(resourceGroup) slotName: staging package: $(Pipeline.Workspace)/drop/**/*.zip - script: | sleep 20 curl --fail --retry 5 --retry-delay 10 https://$(webAppName)-staging.azurewebsites.net/health displayName: Smoke test# ---------- CD : Production ----------- stage: DeployProd dependsOn: DeployStaging jobs: - deployment: Production environment: production # déclenche l'approbation manuelle strategy: runOnce: deploy: steps: - task: AzureAppServiceManage@0 displayName: Swap staging vers production inputs: azureSubscription: $(azureSubscription) Action: 'Swap Slots' WebAppName: $(webAppName) ResourceGroupName: $(resourceGroup) SourceSlot: staging SwapWithProduction: true
Puis dans Azure DevOps : Pipelines â New pipeline â Azure Repos Git â Existing YAML file.
Ătape 5 : ProtĂ©ger la branche main
Repos â Branches â main â Branch policies :
- Revue de code obligatoire (1 reviewer minimum).
- Build validation : le pipeline doit réussir avant de pouvoir fusionner une PR.
- Résolution des commentaires obligatoire.
Résultat : les PR lancent le build et les tests (étape CI uniquement), et seul un merge sur main déclenche le déploiement.
Ătape 6 : GĂ©rer les secrets et la configuration
- Azure Key Vault pour les mots de passe, chaĂźnes de connexion et clĂ©s d’API. Donne Ă l’App Service une Managed Identity et rĂ©fĂ©rence les secrets avec
@Microsoft.KeyVault(SecretUri=...)dans les paramĂštres de l’application. - Utilise des paramĂštres de slot (« Deployment slot setting ») pour les valeurs propres Ă chaque environnement.
- Ne mets jamais de secrets dans le dépÎt ni dans le YAML.
Ătape 7 : Monitoring et retour arriĂšre
- Application Insights pour les requĂȘtes, erreurs, dĂ©pendances et performances. Configure des alertes (taux d’erreur, temps de rĂ©ponse).
- Rollback instantanĂ© : refais un swap des slots. L’ancienne version est toujours dans le slot
stagingaprĂšs le swap.
Alternative : le raccourci depuis Visual Studio
Dans Visual Studio, clic droit sur le projet â Publish â Azure â Azure App Service. L’assistant peut proposer de gĂ©nĂ©rer un workflow GitHub Actions (CI/CD) avec les identifiants Azure dĂ©jĂ configurĂ©s. C’est trĂšs rapide pour dĂ©marrer, mais moins complet qu’un pipeline en plusieurs Ă©tapes avec approbations. Garde-le pour un prototype, et utilise le pipeline YAML ci-dessus pour un projet sĂ©rieux.
Ăvolutions possibles
- Infrastructure as Code : dĂ©crire les ressources Azure avec Bicep ou Terraform plutĂŽt qu’avec des commandes manuelles.
- Scans de sécurité : Defender for DevOps, CodeQL, scan de dépendances.
- Conteneurs : build d’image Docker, push vers Azure Container Registry, dĂ©ploiement sur App Service for Containers ou Azure Container Apps.
- Déploiement canary : le « Testing in production » des slots permet de router un pourcentage du trafic vers
stagingavant le swap.
