SKILL /azure-cicd-dotnet

CI/CD .NET avec Visual Studio et Azure

Ce skill guide la mise en place d’un pipeline complet : un push déclenche le build et les tests, produit un artefact unique, le déploie en staging, attend une approbation, puis bascule en production avec possibilité de retour arrière. Le but est un déploiement reproductible, sécurisé et réversible, pas seulement un pipeline qui passe au vert.

Avant de commencer : clarifier le contexte

Poser (en une seule fois, sans interroger inutilement) les questions dont la réponse change le pipeline :

  • Type d’application : API/site web (App Service), Functions, conteneur (ACR + Container Apps ou AKS).
  • Dépôt : Azure Repos ou GitHub (Azure Pipelines ou GitHub Actions).
  • Version de .NET et nom de la solution et des projets de tests.
  • Un environnement ou deux (staging + production).

Si l’utilisateur n’a pas de préférence, partir sur : ASP.NET Core, App Service Linux, Azure Repos, Azure Pipelines YAML, slot staging + production.

Principes directeurs (et pourquoi)

  • Construire une seule fois, déployer le même artefact partout. Sinon staging ne valide pas ce qui part en production.
  • Échouer vite. Restore, build et tests unitaires avant tout déploiement ; les étapes lourdes viennent après.
  • Pas de secrets dans le dépôt ni dans le YAML. Utiliser Key Vault, des variables protégées et la Managed Identity.
  • Workload Identity Federation pour la service connection : aucun secret à renouveler ni à faire fuiter.
  • Retour arrière trivial : avec les slots, un second swap restaure la version précédente.
  • Pipeline as code : tout est versionné avec le projet.

Procédure

1. Préparer le projet dans Visual Studio

  • Projet de tests (xUnit ou NUnit) qui passe dans Test Explorer.
  • Endpoint de santé : builder.Services.AddHealthChecks(); puis app.MapHealthChecks("/health"); (sert aux smoke tests).
  • Dépôt Git créé (menu Git, Create Git Repository) et poussé vers Azure DevOps ou GitHub.

2. Créer les ressources Azure

Utiliser Azure CLI, ou de préférence Bicep ou Terraform si l’utilisateur veut de l’Infrastructure as Code :

“`bash

az login
az group create -n rg-monapp -l canadaeast
az appservice plan create -n plan-monapp -g rg-monapp --sku S1
az 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
  • Les slots exigent un plan Standard (S1) ou supérieur.
  • Le nom du Web App doit être unique mondialement.
  • Vérifier les runtimes valides avec az webapp list-runtimes plutôt que de se fier à la mémoire.
  • Ajouter Application Insights.

3. Configurer Azure DevOps

  • Service connection Azure Resource Manager en Workload Identity Federation, limitée au groupe de ressources (ex. sc-azure-prod).
  • Environnements staging et production ; ajouter une Approval check sur production.
  • Si le pipeline reste en attente sur une nouvelle organisation, vérifier le parallélisme des agents hébergés.

4. Écrire azure-pipelines.yml

Utiliser le modèle dans references/pipeline-template.md (à la fin de ce fichier). Trois stages : Build (restore, build, tests avec couverture, publish, artefact), DeployStaging (slot + smoke test sur /health), DeployProd (environnement avec approbation, puis swap des slots). Les déploiements ne se déclenchent que sur main.

5. Protéger la branche main

Branch policies : revue obligatoire, build validation (le pipeline doit réussir avant merge), commentaires résolus. Ainsi les PR ne font que la CI, et seul un merge sur main déploie.

6. Secrets et configuration

  • Azure Key Vault + Managed Identity de l’App Service ; références @Microsoft.KeyVault(SecretUri=...) dans les paramètres.
  • Paramètres propres à un environnement marqués comme « Deployment slot setting ».

7. Monitoring et rollback

  • Application Insights, alertes sur taux d’erreur et temps de réponse.
  • Rollback : refaire un swap des slots.

Variantes à proposer selon le contexte

  • Conteneurs : build et push d’image vers ACR, scan Trivy, déploiement sur App Service for Containers ou Container Apps.
  • GitHub Actions : même structure (jobs build, staging, production avec environment:), identifiants via OIDC.
  • Raccourci Visual Studio (clic droit, Publish, Azure) : bon pour un prototype ; le signaler comme moins complet (pas d’approbation ni de staging).
  • Canary : Testing in production des slots pour router un pourcentage du trafic avant le swap.
  • DevSecOps : CodeQL, scan des dépendances, détection de secrets.

Checklist avant de livrer

  • [ ] Aucun secret dans le dépôt ni dans le YAML
  • [ ] Même artefact déployé en staging et en production
  • [ ] Smoke test sur /health avant le swap
  • [ ] Approbation configurée sur l’environnement production
  • [ ] Branch policy avec build validation sur main
  • [ ] Rollback décrit à l’utilisateur (swap inverse)
  • [ ] Noms, régions et versions de runtime adaptés au projet réel

Format de réponse

Répondre dans la langue de l’utilisateur. Donner d’abord une vue d’ensemble courte (schéma en une ligne du flux), puis les étapes numérotées avec les commandes et fichiers complets, puis la checklist. Terminer par les décisions encore ouvertes à confirmer. Ne pas inventer de noms de tâches Azure Pipelines : en cas de doute sur une tâche ou un paramètre, le dire et renvoyer à la documentation Microsoft.

Modèle de pipeline (références)

“`yaml

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:
- 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
- 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
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
- stage: DeployProd
dependsOn: DeployStaging
jobs:
- deployment: Production
environment: production
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

===========================================================

J’ai rédigé le skill azure-cicd-dotnet.

Ce qu’il contient :

  • Déclencheur : pipeline, déploiement Azure, azure-pipelines.yml, slots, service connection, Azure DevOps, CI/CD avec Visual Studio. La description est volontairement « insistante » pour qu’il se déclenche même si tu ne dis pas « CI/CD ».
  • Clarification initiale : il demande le type d’application, le dépôt (Azure Repos ou GitHub) et la version de .NET, avec des valeurs par défaut si tu n’as pas de préférence.
  • Principes avec leur raison : un seul artefact déployé partout, échec rapide, aucun secret dans le dépôt, Workload Identity Federation, rollback par swap.
  • Les 7 étapes : projet, ressources Azure, Azure DevOps, YAML, protection de main, secrets, monitoring.
  • Variantes : conteneurs, GitHub Actions, canary, DevSecOps.
  • Checklist finale et format de réponse.
  • Gabarit YAML complet intégré en bas du fichier.

Limites :

  • Je n’ai pas pu lancer de tests dans cet environnement (pas d’exécution de code ni de sous-agents), donc le skill n’a pas été évalué sur des cas réels. Je te suggère de l’essayer sur 2 ou 3 demandes, par exemple « crée-moi un pipeline pour mon API .NET 8 sur Azure » ou « ajoute l’approbation avant la production », puis de me dire ce qui cloche.
  • Les noms de tâches Azure Pipelines (AzureWebApp@1, AzureAppServiceManage@0) et les runtimes évoluent. Vérifie-les dans la documentation Microsoft avant un usage réel.