WIKI
AZ-400 DevOps Engineer

05 · Concevoir et implémenter les déploiements

30 min de lecture Mis à jour le 21 octobre 2026
Sur cette page

Version : 1.1 · Date : 2026-10-22 · Domaine 3 de l'examen : Design and implement build and release pipelines (50 à 55 %), bloc Design and implement deployments

En une phrase : un bon déploiement sépare deux décisions, où tourne la nouvelle version (blue-green, canary, ring, rolling, deployment slots) et qui voit la fonctionnalité (feature flags), avance par petits pas surveillés, sait revenir en arrière ou corriger vers l'avant, et traite la base de données comme la partie la plus délicate.

Déployer n'est pas exposer : deux leviers pour réduire le risque

Ce que l'examen demande#

Texte officiel du guide d'étude AZ-400 (compétences au 27 juillet 2026) :

# Compétence mesurée (guide officiel, en anglais) Section
1 Design a deployment strategy, including blue-green, canary, ring, progressive exposure, feature flags, and A/B testing 2
2 Design a pipeline to ensure that dependency deployments are reliably ordered 3
3 Plan for minimizing downtime during deployments by using load balancing, rolling deployments, and deployment slot usage and swap 4
4 Design a hotfix path plan for responding to high-priority code fixes 5
5 Design and implement a resiliency strategy for deployment 6
6 Implement feature flags by using Azure App Configuration Feature Manager 7
7 Implement application deployment by using containers, binaries, and scripts 8
8 Implement a deployment that includes database tasks 9

Les pipelines eux-mêmes (YAML, stages, environments, checks et approvals) sont au chapitre 04, l'infrastructure as code au chapitre 06, les secrets et service connections au chapitre 07.


1. Les bases à maîtriser#

1.1 Le vocabulaire#

Terme Ce qu'il veut dire
Deployment Installer une nouvelle version sur une infrastructure
Release (au sens « mise en service ») Rendre une fonctionnalité visible aux utilisateurs ; avec un feature flag, c'est une décision distincte du déploiement
Progressive exposure Exposer la nouvelle version à des groupes de plus en plus larges, en vérifiant la santé entre chaque étape
Bake time Le temps d'observation entre deux groupes ; Microsoft le compte en heures et en jours, pas en minutes, et le fait croître d'un groupe à l'autre
Health model L'ensemble des signaux qui disent si la charge de travail va bien (erreurs, latence, usage) ; un signal négatif arrête le déploiement
Roll back Revenir à la dernière configuration connue bonne
Roll forward Corriger pendant le déploiement (hotfix) au lieu de revenir en arrière
N / N-1 Pendant un déploiement progressif, la version N et la version N-1 tournent en même temps : tout (API, base, messages) doit supporter les deux

1.2 Les quatre principes des safe deployment practices#

Le guide Well-Architected (OE:11) résume la démarche en quatre idées :

  1. Sécurité et cohérence : aucun déploiement n'est « à faible risque » ; tout passe par le même chemin automatisé.
  2. Exposition progressive : limiter le blast radius d'un problème.
  3. Health model : chaque phase ne commence qu'après des contrôles de santé réussis.
  4. Détection : au premier problème, on arrête et on lance la récupération.

Petits déploiements fréquents plutôt que gros déploiements rares ; post-mortems blameless après un incident.


2. Concevoir une stratégie de déploiement#

Blue-green, canary, ring, rolling : ce qui bascule et à quel rythme

2.1 Les stratégies côte à côte#

Stratégie Principe Retour arrière Coût et contraintes Outils Azure typiques
Blue-green Deux environnements identiques, chacun capable de toute la charge ; on teste green, puis on bascule le trafic (en une fois ou par vagues) Rebasculer vers blue Deux environnements complets ; état et base partagés à gérer Deployment slots + swap, Front Door / Traffic Manager, deux clusters AKS
Canary Une petite part du trafic va d'abord vers la nouvelle version, puis on augmente Renvoyer 0 % vers le canary Il faut mesurer finement la santé du canary Traffic % d'un slot, deployment job canary sur Kubernetes, poids Front Door
Ring-based Des groupes d'utilisateurs successifs (interne, early adopters, tous) Arrêter avant l'anneau suivant Bake time long, plusieurs versions en production Stages de pipeline par anneau, feature flags par groupe
Rolling Les instances d'un même pool sont remplacées par lots Redéployer l'ancienne version, lot par lot Capacité réduite pendant le lot (sauf surge) Deployment job rolling (VM), VMSS Rolling upgrade policy, rolling update Kubernetes
Progressive exposure Le principe général derrière canary et ring — — Combinaison des précédents
Feature flags Le code est déployé partout mais désactivé ; on l'active pour qui on veut (dark launch, kill switch) Désactiver le flag, sans redéployer Dette technique si on ne retire pas les flags Azure App Configuration Feature Manager (section 7)
A/B testing Deux variantes (ou plus) servies à des segments, pour mesurer laquelle est meilleure Revenir à une variante Il faut de la télémétrie et une hypothèse à tester Variant feature flags (allocation par percentile)

Distinction d'examen : un canary répartit du trafic (ou des instances) ; un ring répartit des utilisateurs ; un feature flag ne change pas l'endroit où tourne le code, seulement ce qu'il montre. Blue-green et canary se combinent souvent : green reçoit d'abord une petite part du trafic.

2.2 Choisir#

flowchart TD
    A["Nouvelle version à livrer"] --> B{"Changement visible<br/>pour l'utilisateur ?"}
    B -- "Oui" --> C["Feature flag :<br/>déployer éteint, activer par groupes"]
    B -- "Non (technique)" --> D{"Deux environnements<br/>possibles ?"}
    C --> D
    D -- "Oui (App Service, AKS, stamps)" --> E{"Valider sur du vrai trafic<br/>avant de tout basculer ?"}
    D -- "Non (un seul pool de VM)" --> F["Rolling par lots<br/>avec health checks"]
    E -- "Oui" --> G["Canary : 10 %, 20 %, puis 100 %"]
    E -- "Non" --> H["Blue-green : swap, rebascule possible"]
    G --> I["Grandes populations ou régions :<br/>rings avec bake time croissant"]

2.3 Ce qui doit être vrai pour que ça marche#

  • Versionner les artefacts : on ne peut revenir en arrière que vers une version identifiable.
  • Compatibilité N / N-1 : l'API, le schéma de base, les messages en file doivent fonctionner avec les deux versions.
  • Branching : Microsoft recommande release flow ou trunk-based plutôt que Gitflow ou des branches par environnement (voir chapitre 02).
  • Environnements de staging qui ressemblent à la production, contrôles avant déploiement (revue, scans, conformité), et plusieurs types de tests.

3. Ordonner les déploiements dépendants#

Ordonner les déploiements dépendants : chaque étape attend la précédente

Le principe : on déploie de la donnée vers l'interface. L'infrastructure d'abord, puis la base (avec un schéma compatible avec l'ancienne application), puis les API, puis les clients qui les consomment, puis les tests de fumée qui ouvrent l'environnement suivant.

Azure Pipelines : dependsOn et condition au niveau des stages (ou des jobs). Sans dependsOn, les stages s'enchaînent dans l'ordre du fichier ; dependsOn: [] les rend parallèles.

stages:
- stage: Infra
  jobs:
  - deployment: DeployInfra
    environment: prod
    strategy:
      runOnce:
        deploy:
          steps:
          - script: echo "az deployment group create … (Bicep)"

- stage: Database
  dependsOn: Infra
  condition: succeeded()
  jobs:
  - deployment: DeployDb
    environment: prod
    strategy:
      runOnce:
        deploy:
          steps:
          - script: echo "sqlpackage /Action:Publish …"

- stage: Api
  dependsOn: Database
  condition: succeeded()
  jobs:
  - deployment: DeployApi
    environment: prod
    strategy:
      runOnce:
        deploy:
          steps:
          - script: echo "déploiement de l'API dans le slot staging, puis swap"

Pour passer une valeur d'un stage à l'autre (par exemple l'URL de l'API créée par l'infra), on publie une output variable (##vso[task.setvariable variable=…;isOutput=true]) et on la lit avec stageDependencies.<stage>.<job>.outputs['…'].

GitHub Actions : needs: au niveau des jobs. Les jobs sans needs tournent en parallèle ; un job ne démarre que si ceux qu'il attend ont réussi. L'environment: d'un job porte ses règles de protection.

jobs:
  infra:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - run: echo "déploiement Bicep"
  database:
    needs: infra
    runs-on: ubuntu-latest
    environment: production
    steps:
      - run: echo "déploiement du schéma"
  api:
    needs: [infra, database]
    runs-on: ubuntu-latest
    environment: production
    steps:
      - run: echo "déploiement de l'API"

Dans l'IaC elle-même, Bicep ordonne les ressources grâce aux références entre elles (dépendances implicites) ; l'ordre des applications reste l'affaire du pipeline.


4. Minimiser l'indisponibilité : load balancing, rolling et deployment slots#

Minimiser l'indisponibilité : retirer, mettre à jour, remettre derrière un répartiteur

4.1 La règle#

Zéro coupure suppose trois choses : assez de capacité pendant la mise à jour, une santé vérifiée avant qu'une instance reçoive du trafic (health probe), et des connexions vidées avant d'arrêter une instance.

Levier Comment il évite la coupure
Load Balancer, Application Gateway, Front Door, Traffic Manager Sortir une instance ou une région du pool, la mettre à jour, la remettre ; répartir le trafic par poids (Traffic Manager Weighted, poids des origins de Front Door)
Rolling deployment Mettre à jour par lots ; le reste du pool sert le trafic
Deployment slots + swap Chauffer la nouvelle version dans un slot, puis échanger le routage : aucune requête perdue

4.2 Rolling sur des VM#

  • Deployment job rolling (Azure Pipelines) : uniquement pour des ressources VM d'un environment ; maxParallel fixe le nombre ou le pourcentage de cibles mises à jour en même temps (5 cibles maximum par itération dans l'exemple officiel).
  • Virtual Machine Scale Sets : trois upgrade policy modes : Automatic (aucune garantie d'ordre, toutes les instances peuvent tomber en même temps : réservé au dev/test), Manual (vous choisissez quand), Rolling (par lots).
# Passer un scale set en Rolling, lots de 10 %, avec MaxSurge (nouvelles instances avant de retirer les anciennes)
az vmss update --name vmss-web --resource-group rg-web \
  --set upgradePolicy.mode=Rolling \
  --max-batch-instance-percent 10 --max-unhealthy-instance-percent 20 \
  --max-unhealthy-upgraded-instance-percent 20 --prioritize-unhealthy-instances true \
  --pause-time-between-batches PT2S --max-surge true

Le mode Rolling exige un health probe de load balancer ou l'Application Health extension ; Microsoft conseille de créer le scale set en Manual, de vérifier que la santé remonte bien, puis de passer en Rolling. maxBatchInstancePercent vaut 20 % par défaut.

4.3 Deployment slots (App Service et Functions)#

Deployment slots : chauffer en staging, puis basculer sans coupure

  • Disponibles à partir des plans Standard, Premium ou Isolated ; le nombre de slots dépend du niveau (5 en Standard). Pas de coût supplémentaire.
  • Chaque slot est une application vivante, avec son propre host name (sitename-slotname.azurewebsites.net).
  • Un nouveau slot est vide, même si l'on clone la configuration ; un private endpoint n'est pas cloné.

Ce que fait le swap, dans l'ordre : les réglages propres au slot cible (slot settings, continuous deployment, App Service authentication) sont appliqués au slot source, qui redémarre ; App Service attend que toutes les instances redémarrent ; il chauffe chaque instance (requête sur / ou applicationInitialization) ; puis il échange les règles de routage. Tout le travail se fait sur le slot source : la production reste en ligne même si le swap échoue. Garder la production en cible.

# Créer un slot, y déployer, puis l'échanger avec la production
az webapp deployment slot create --name app-web --resource-group rg-web --slot staging
az webapp deployment slot swap --resource-group rg-web --name app-web --slot staging --target-slot production

# Swap with preview (en deux temps) : appliquer les réglages de prod au slot, vérifier, puis terminer… ou annuler
az webapp deployment slot swap -g rg-web -n app-web --slot staging --target-slot production --action preview
az webapp deployment slot swap -g rg-web -n app-web --slot staging --target-slot production --action swap
az webapp deployment slot swap -g rg-web -n app-web --slot staging --target-slot production --action reset

# Un réglage qui ne doit pas suivre le code (« Deployment slot setting »)
az webapp config appsettings set -n app-web -g rg-web --slot staging \
  --settings ENVIRONNEMENT=staging --slot-settings ENVIRONNEMENT

# Canary sur un slot : 15 % du trafic de production vers staging
az webapp traffic-routing set --resource-group rg-web --name app-web --distribution staging=15
Réglages échangés (suivent le code) Réglages non échangés (restent dans le slot)
App settings et connection strings (sauf ceux marqués Deployment slot setting), version du runtime, 32/64 bits, WebSockets, handler mappings, certificats publics, contenu des WebJobs, Hybrid Connections, service endpoints, CDN, path mappings Custom domain names, certificats non publics et TLS, scale, planificateurs WebJobs, IP restrictions, Always On, réglages de logs de diagnostic, CORS, managed identities, VNet integration, protocoles (HTTPS Only, version TLS), publishing endpoints, réglages finissant par _EXTENSION_VERSION

Autres points d'examen :

  • Swap with preview : impossible si l'authentification de site est activée sur l'un des slots.
  • Auto swap : chaque déploiement dans le slot source est automatiquement échangé après warm-up ; pas pris en charge sur Linux ni Web App for Containers.
  • Warm-up personnalisé : applicationInitialization dans Web.config, ou les app settings WEBSITE_SWAP_WARMUP_PING_PATH (ex. /statuscheck) et WEBSITE_SWAP_WARMUP_PING_STATUSES (ex. 200,202).
  • Retour arrière : refaire immédiatement le même swap.
  • Routage manuel : le paramètre x-ms-routing-name=staging (ou self pour la production) épingle une session ; un client routé automatiquement reste sur son slot pendant une heure (cookie x-ms-routing-name).

Dans un pipeline : AzureWebApp@1 avec deployToSlotOrASE: true et slotName: staging, puis AzureAppServiceManage@0 avec SwapWithProduction: true ; côté GitHub, azure/webapps-deploy@v3 avec slot-name: staging, puis le swap en CLI.


5. Le chemin d'un hotfix#

Le chemin d'un hotfix : corriger dans main, puis cherry-pick vers la release

Avec le Release Flow de Microsoft : main est toujours buildable ; à chaque fin de sprint, une branche releases/M129 part de main et va en production ; les release branches ne sont jamais fusionnées dans main.

Pour un correctif urgent :

  1. créer une branche courte depuis main, faire la revue, compléter la pull request (avec ses branch policies) ;
  2. depuis la page de la PR, cherry-pick vers la release branch : cela crée une nouvelle PR ciblant la release, revue et testée à son tour ;
  3. déployer depuis la release branch, d'abord sur le premier ring (en minutes), puis progressivement.

Corriger d'abord dans main garantit que le bug ne revient pas à la release suivante. Si deux releases sont en production en même temps (déploiement par rings en cours), le hotfix est porté sur les deux.

Ce que dit Well-Architected pour l'urgence (emergency SDP protocols) : on peut accélérer les approbations, les tests et réduire le bake time, mais pas supprimer les gates ; il faut définir à l'avance qui peut approuver l'accélération et sur quels critères.

flowchart LR
    A["Incident en production"] --> B["Branche fix depuis main"]
    B --> C["PR vers main<br/>branch policies, tests"]
    C --> D["Cherry-pick vers releases/Mxxx<br/>nouvelle PR"]
    D --> E["Déploiement accéléré<br/>ring 0 puis rings suivants"]
    E --> F{"Santé OK ?"}
    F -- "Oui" --> G["Fin du hotfix"]
    F -- "Non" --> H["Arrêt, roll back<br/>ou nouveau correctif"]

6. Une stratégie de résilience pour le déploiement#

Un déploiement résilient détecte le problème tôt et sait récupérer :

Option de récupération Quand Exemple
Roll back Le changement est réversible (code, configuration) Rebasculer un swap, KubernetesManifest@1 action: reject, redéployer l'artefact N-1
Roll forward Le retour arrière est risqué ou impossible (schéma de base déjà migré) Hotfix via la release branch
Redéployer une infrastructure neuve L'environnement est corrompu IaC à partir de la dernière configuration connue bonne
Désactiver un feature flag La fonctionnalité pose problème, pas le déploiement Kill switch dans App Configuration
Restaurer les données Données abîmées Point-in-time restore (Azure SQL Database, SQL Managed Instance, Cosmos DB, MySQL, PostgreSQL)

Les briques du pipeline :

  • Lifecycle hooks d'un deployment job : postRouteTraffic pour surveiller la santé après bascule, on: failure pour nettoyer ou revenir en arrière (section 8.2).
  • Checks et approvals sur l'environment (chapitre 04) : approbation manuelle, business hours, requête Azure Monitor, etc.
  • Circuit breakers côté application, pour couper le trafic vers un service malade.
  • Versioning des artefacts et rétention suffisante pour pouvoir redéployer l'ancienne version.
flowchart TD
    A["Signal de santé négatif<br/>pendant le bake time"] --> B["Arrêter le déploiement"]
    B --> C{"Qu'est-ce qui pose problème ?"}
    C -- "Une fonctionnalité" --> D["Éteindre le feature flag"]
    C -- "Le code ou la config,<br/>sans changement de schéma" --> E["Roll back :<br/>swap inverse, reject, version N-1"]
    C -- "Après une migration<br/>de base" --> F["Roll forward :<br/>hotfix compatible"]
    C -- "L'environnement" --> G["Recréer depuis l'IaC"]

7. Feature flags avec Azure App Configuration Feature Manager#

Feature flags avec Azure App Configuration : activer sans redéployer

7.1 Les trois usages#

Usage À quoi il sert Capacités
Switch On/off instantané pour tous Kill switch d'une fonctionnalité ou d'une dépendance, mode maintenance
Rollout Exposer progressivement Pourcentage d'utilisateurs, utilisateurs et groupes ciblés (canary ou staged rollout)
Experiment Comparer des variantes Variant feature flags, allocation par percentile, A/B testing, mesure d'impact

7.2 Les filtres#

Un feature filter est une condition évaluée à chaque lecture du flag :

Filtre intégré Effet Paramètres
Time window (Microsoft.TimeWindow) Active pendant une fenêtre de temps Start, End (un seul des deux suffit)
Targeting (Microsoft.Targeting) Active pour une audience Users, Groups (chacun avec RolloutPercentage), DefaultRolloutPercentage, Exclusion (users, groups)
Percentage (bibliothèque .NET : PercentageFilter) Active pour un pourcentage des évaluations Value
Filtres personnalisés Votre propre règle (navigateur, région…) Implémentation de IFeatureFilter

Avec plusieurs filtres, requirement_type vaut Any par défaut (un seul filtre vrai suffit) ou All (tous doivent être vrais). Une exclusion l'emporte toujours dans Targeting.

7.3 Variant feature flags#

Un variant a un nom et une valeur de configuration optionnelle (un objet JSON). L'allocation dit qui reçoit quel variant : par user, puis par group, puis par percentile (dans cet ordre) ; un seed rend la répartition stable. Deux défauts : DefaultWhenEnabled (pour les percentiles non attribués) et DefaultWhenDisabled (quand le flag est désactivé : c'est le kill switch, tout le monde reçoit ce variant). status_override (None, Enabled, Disabled) permet à un variant de forcer l'état du flag.

7.4 Mise en œuvre#

# Créer un flag, le décrire, lui ajouter un filtre Targeting, puis l'activer (authentification Entra : --auth-mode login)
az appconfig feature set --name appcs-web --feature Beta --description "Nouveau parcours de paiement" --auth-mode login
az appconfig feature filter add --name appcs-web --feature Beta --filter-name Microsoft.Targeting --auth-mode login \
  --filter-parameters Audience='{"Users":["[email protected]"],"Groups":[{"Name":"Ring0","RolloutPercentage":100}],"DefaultRolloutPercentage":10}'
az appconfig feature enable --name appcs-web --feature Beta --auth-mode login

La clé d'un flag commence par le préfixe réservé .appconfig.featureflag/ ; un label permet d'avoir des valeurs par environnement. Côté application (.NET), sans clé :

// Lecture des feature flags avec l'identité de l'application (rôle App Configuration Data Reader sur le store)
builder.Configuration.AddAzureAppConfiguration(options =>
{
    options.Connect(new Uri(endpoint), new DefaultAzureCredential())
           .UseFeatureFlags();          // rafraîchissement par défaut : 30 secondes
});
builder.Services.AddAzureAppConfiguration();
builder.Services.AddFeatureManagement();   // TimeWindow, Targeting et Percentage enregistrés automatiquement (v3+)

// Dans le code : if (await featureManager.IsEnabledAsync("Beta")) { … }  ou l'attribut [FeatureGate("Beta")]

Pour Targeting, l'application fournit un targeting context (identifiant de l'utilisateur et ses groupes) : .WithTargeting().

Bonne pratique : un flag a une durée de vie. Retirez-le du code et du store une fois la fonctionnalité généralisée, sinon il devient de la dette technique et une source de comportements inattendus.


8. Déployer des conteneurs, des binaires et des scripts#

8.1 Quelle tâche pour quelle cible#

Cible Azure Pipelines GitHub Actions
App Service (package zip, binaires) AzureWebApp@1 (slotName possible) azure/webapps-deploy@v3 (package, slot-name)
App Service (conteneur) AzureWebAppContainer@1 azure/webapps-deploy@v3 (images)
Azure Functions AzureFunctionApp@2 (zipDeploy, runFromPackage, slots, Flex Consumption) Azure/functions-action
Functions en conteneur AzureFunctionAppContainer@1 —
AKS / Kubernetes KubernetesManifest@1 (deploy, promote, reject, createSecret, stratégie canary) azure/k8s-deploy
Swap, démarrer, arrêter une app AzureAppServiceManage@0 az webapp deployment slot swap dans un step
Scripts AzureCLI@2, AzurePowerShell@5 azure/cli, run: après azure/login
VM (scripts, IIS) Deployment job sur un environment de type VM (IISWebAppDeploymentOnMachineGroup@0, scripts) Runner self-hosted
Images de VM PackerBuild@1, AzureVmssDeployment@0 —

Authentification : service connection avec workload identity federation côté Azure Pipelines ; azure/login@v2 en OIDC côté GitHub (permissions: id-token: write). Pour Functions et App Service, Microsoft propose une user-assigned managed identity fédérée avec le dépôt et le rôle Website Contributor sur l'application (chapitre 07).

# GitHub Actions : déployer dans le slot staging sans secret, puis échanger
permissions:
  id-token: write
  contents: read
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
      - uses: azure/webapps-deploy@v3
        with:
          app-name: app-web
          slot-name: staging
          package: ./output
      - run: az webapp deployment slot swap -g rg-web -n app-web --slot staging --target-slot production

8.2 Le deployment job et ses lifecycle hooks#

Deployment job : la stratégie se déroule en lifecycle hooks

Un deployment job (- deployment:) est le type de job recommandé pour déployer : il enregistre l'historique sur l'environment (jusqu'à la ressource) et applique une stratégie. Points d'examen :

  • il ne clone pas le dépôt automatiquement (- checkout: self si besoin) ; les artefacts sont téléchargés automatiquement dans le hook deploy seulement (- download: none pour l'éviter) ;
  • hooks : preDeploy, deploy, routeTraffic, postRouteTraffic, puis on: success ou on: failure ;
  • runOnce : chaque hook une fois ; rolling : VM uniquement, hooks par lot de maxParallel ; canary : preDeploy une fois, puis deploy / routeTraffic / postRouteTraffic pour chaque valeur de increments ;
  • variables : strategy.name, strategy.action (deploy, promote, reject), strategy.increment.
# Canary sur AKS : 10 %, puis 20 %, surveillance, puis promotion ou rejet
jobs:
- deployment: DeployCanary
  environment: aks-prod.bookings      # ressource Kubernetes (namespace) de l'environment
  pool:
    vmImage: ubuntu-latest
  strategy:
    canary:
      increments: [10, 20]
      deploy:
        steps:
        - task: KubernetesManifest@1
          inputs:
            action: $(strategy.action)
            namespace: bookings
            strategy: $(strategy.name)
            percentage: $(strategy.increment)
            manifests: $(Pipeline.Workspace)/manifests/*
      postRouteTraffic:
        pool: server
        steps:
        - task: Delay@1
          inputs:
            delayForMinutes: '10'
      on:
        failure:
          steps:
          - script: echo "rejet du canary"   # KubernetesManifest@1 action: reject

Pour AKS, les stratégies côté cluster (rolling update des pods, PodDisruptionBudget, blue-green de clusters) sont dans le parcours AKS, chapitre 04 ; le safe rollout d'endpoints de modèles ML dans AI-300, chapitre 04.

Cluster AKS privé : l'API server n'est pas joignable depuis un agent Microsoft-hosted ; utilisez un agent self-hosted (ou un Managed DevOps Pool) dans un réseau qui voit le cluster.


9. Un déploiement qui inclut la base de données#

Déployer avec une base de données : le schéma avance, on roule vers l'avant

9.1 Le principe : N et N-1, puis roll forward#

Microsoft (Eliminate downtime through versioned service updates) applique trois règles :

  1. Mettre à jour les couches séparément : la base et l'application ne changent pas au même instant ; c'est généralement l'application qui absorbe la complexité, en sachant parler aux schémas N et N-1.
  2. On déploie d'abord les binaires (on peut encore revenir en arrière), puis on lance la mise à jour de la base.
  3. Une fois la base migrée, on roule vers l'avant : une migration en ligne est complexe, son retour arrière échouerait probablement aussi.

En pratique, on ajoute (nouvelle colonne ou table), on déploie une application compatible avec les deux formes, on migre les données (parfois en plusieurs releases), et on retire l'ancien seulement quand plus rien ne l'utilise. Ce découpage est souvent appelé expand / contract hors de la documentation Microsoft.

9.2 Les outils#

Approche Commande ou tâche Points d'attention
SQL project (.dacpac), schéma déclaratif SqlAzureDacpacDeployment@1 (deployType: DacpacTask, DeploymentAction: Publish) ou sqlpackage /Action:Publish La tâche ne tourne que sur agent Windows (sur Linux, appeler SqlPackage) ; elle peut ouvrir et refermer la règle de pare-feu de l'agent (IpDetectionMethod: AutoDetect, DeleteFirewallRule: true) ; authentification servicePrincipal possible ; actions DeployReport et DriftReport pour prévisualiser
EF Core migration bundle dotnet ef migrations bundle, puis efbundle --connection … Recommandé pour le déploiement automatisé ; n'exige ni SDK ni sources à l'exécution ; depuis EF Core 9, prend un verrou de migration sur la base (un script SQL, lui, n'en prend pas)
Script SQL idempotent dotnet ef migrations script --idempotent -o artifacts/migrate.sql Quand un DBA doit relire et approuver ; on déploie le script approuvé, pas un script régénéré
Migration au démarrage de l'app context.Database.MigrateAsync() À éviter en production : droits élevés pour l'application, pas de revue ; le verrou d'EF Core 9+ évite la corruption entre instances, mais Microsoft préfère une étape de déploiement séparée
# Agent Linux : publier un .dacpac avec SqlPackage
steps:
- task: UseDotNet@2
  inputs:
    packageType: sdk
    version: '8.x'
- script: dotnet tool install --global microsoft.sqlpackage
  displayName: Installer SqlPackage
- script: |
    sqlpackage /Action:Publish \
      /SourceFile:$(Pipeline.Workspace)/drop/Database.dacpac \
      /TargetConnectionString:"$(ConnectionString)"
  displayName: Déployer le schéma

Bonnes pratiques :

  • une identité de déploiement qui a les droits de schéma, distincte de l'identité de l'application qui ne lit et n'écrit que les données ; la connection string vient de Key Vault ou d'une variable secrète, jamais du YAML ;
  • un publish profile qui contient des secrets va dans les secure files de la Library ;
  • un gate d'approbation (environment check) avant l'étape de base en production ;
  • un script de retour arrière (migrations script avec un from plus récent que le to) existe, mais ne reconstitue pas les données supprimées : à tester sur une copie de la production ;
  • en dernier recours, le point-in-time restore de la base.

10. Labs conseillés#

Dans un abonnement et une organisation Azure DevOps (ou un dépôt GitHub) de test ; supprimer le groupe de ressources à la fin.

  1. Slots et swap with preview (App Service S1, quelques euros par jour) : créer un slot staging, y déployer une version qui affiche son numéro, marquer un app setting ENV comme Deployment slot setting, faire un swap with preview. Résultat attendu : la production sert v2 sans coupure, ENV est resté dans chaque slot, un second swap ramène v1.
  2. Canary sur un slot : az webapp traffic-routing set --distribution staging=20, puis appeler l'URL de production depuis plusieurs navigateurs. Résultat attendu : environ 20 % des sessions portent le cookie x-ms-routing-name=staging.
  3. Feature flag avec Targeting (App Configuration Free) : créer le flag Beta avec un filtre Targeting (Ring0 à 100 %, défaut 0 %), le lire depuis une petite application avec DefaultAzureCredential et le rôle App Configuration Data Reader. Résultat attendu : seuls les utilisateurs du groupe voient la fonctionnalité ; désactiver le flag la masque sans redéployer.
  4. Pipeline multi-stage ordonné : stages Infra → Database → Api avec dependsOn, un environment prod avec une approbation, et un deployment job runOnce qui a un hook on: failure. Résultat attendu : faire échouer volontairement Database bloque Api ; l'historique de déploiement apparaît sur l'environment.
  5. Base de données N / N-1 (Azure SQL Database serverless, coût faible) : ajouter une colonne nullable par .dacpac, déployer une application qui fonctionne avec ou sans la colonne, migrer les données, puis retirer l'ancienne colonne dans une release suivante. Résultat attendu : aucune erreur applicative pendant les étapes.

11. Pièges d'examen#

Situation dans la question Réponse attendue Pourquoi
Tester une fonctionnalité sur 5 % des utilisateurs sans redéployer Feature flag avec filtre Targeting (ou pourcentage) L'exposition est découplée du déploiement
Envoyer 10 % du trafic vers la nouvelle version d'une Web App Traffic % sur un deployment slot (ou canary) Le routage par slot répartit le trafic
Comparer deux variantes et mesurer laquelle convertit mieux A/B testing avec variant feature flags Allocation par percentile + télémétrie
Déployer d'abord à l'équipe interne, puis aux early adopters, puis à tous Ring-based deployment Des groupes d'utilisateurs successifs
Revenir instantanément en arrière après un swap raté Refaire le même swap L'ancienne version est dans le slot source
Valider la nouvelle version avec les réglages de production avant de basculer Swap with preview Pause après l'application des réglages cibles
Auto swap demandé sur une Web App Linux Impossible : auto swap non pris en charge sur Linux et Web App for Containers Limite documentée
Un app setting doit rester propre à chaque slot Deployment slot setting (--slot-settings) Sinon il suit le code
La managed identity ou la VNet integration « disparaît » après un swap Ces réglages ne sont pas échangés : configurer chaque slot Réglages propres au slot
Deployment slots sur un plan Basic Impossible : Standard, Premium ou Isolated Niveau minimal
Rolling deployment sur Kubernetes avec un deployment job Le rolling des deployment jobs ne vise que des VM ; sur Kubernetes, utiliser canary ou le rolling update natif Limite documentée
VMSS : toutes les instances redémarrent en même temps Upgrade policy Automatic ; passer en Rolling (avec health probe) Automatic ne garantit rien
Le deployment job ne trouve pas le code source Ajouter - checkout: self Un deployment job ne clone pas le dépôt
La correction d'un bug de production disparaît à la release suivante Corriger d'abord dans main, puis cherry-pick vers la release Release Flow
Hotfix urgent : supprimer les tests pour aller plus vite ? Non : accélérer les gates et le bake time, pas les supprimer Emergency SDP protocols
Revenir en arrière après une migration de schéma Roll forward de préférence Le retour arrière d'une base migrée est risqué
SqlAzureDacpacDeployment@1 échoue sur un agent Ubuntu La tâche ne tourne que sur Windows ; appeler SqlPackage sur Linux Prérequis de la tâche
L'application applique elle-même les migrations au démarrage en production À éviter : migration bundle ou script idempotent dans le pipeline Droits élevés, pas de revue
Le DBA doit approuver le SQL exact Script idempotent généré en CI + approval sur l'environment On déploie le script approuvé
Le stage API démarre avant la fin du stage Database Ajouter dependsOn: Database et condition: succeeded() Ordre explicite
GitHub : deux jobs de déploiement tournent en même temps Ajouter needs: Sans needs, les jobs sont parallèles
Un flag reste dans le code un an après la généralisation Le retirer Dette technique
Feature flag, deux filtres, la fonctionnalité doit exiger les deux requirement_type: All Any par défaut
Variant feature flag désactivé : quel variant reçoivent les utilisateurs ? DefaultWhenDisabled C'est le kill switch

12. Scénarios corrigés#

1. Contoso déploie une Web App en plan Premium. Elle veut zéro coupure, pouvoir revenir en arrière en quelques secondes et valider la version avec la vraie configuration de production avant de basculer. Que faire ?

Déployer dans un deployment slot staging, faire un swap with preview (les réglages de production sont appliqués au slot, on vérifie), puis terminer le swap. Retour arrière : refaire le même swap.

2. Après un swap, l'application de production n'arrive plus à lire Key Vault. Pourtant tout marchait en staging. Pourquoi ?

Les managed identities ne sont pas échangées : la production utilise sa propre identité, qui n'a peut-être pas les droits. Donner le rôle Key Vault Secrets User aux identités des deux slots (ou utiliser une user-assigned identity partagée).

3. Fabrikam veut livrer un nouveau moteur de recommandation, d'abord aux employés, puis à 10 % des clients, sans redéployer à chaque étape. Quelle solution ?

Un feature flag dans Azure App Configuration avec un filtre Targeting : groupe Employes à 100 %, DefaultRolloutPercentage à 10 ; on augmente le pourcentage au fil du temps. Kill switch en cas de problème.

4. L'équipe marketing veut savoir laquelle de deux pages de paiement convertit le mieux. Que proposer ?

Un variant feature flag (deux variants, allocation 50/50 par percentile, seed stable) et la télémétrie de la conversion : c'est de l'A/B testing.

5. Un pipeline déploie l'API avant que la migration de base soit terminée, ce qui provoque des erreurs. Comment le corriger ?

Mettre l'API dans un stage qui a dependsOn: Database et condition: succeeded() ; et rendre la migration compatible avec l'ancienne API (N-1), pour que l'ordre ne soit plus critique.

6. Un bug critique est découvert en production (release releases/M130). Le développeur veut corriger directement dans la release branch. Quelle est la bonne démarche selon Release Flow ?

Corriger dans une branche courte depuis main, PR vers main, puis cherry-pick vers releases/M130 (nouvelle PR), et déployer depuis la release par rings. Sinon le bug reviendrait à la release M131.

7. Une flotte de VM derrière un Load Balancer doit être mise à jour sans perte de capacité. Quelle stratégie ?

VMSS avec upgrade policy Rolling, maxBatchInstancePercent faible, health probe ou Application Health extension, et MaxSurge pour créer les nouvelles instances avant de retirer les anciennes. Ou un deployment job rolling avec maxParallel sur un environment de VM.

8. Le DBA exige de relire chaque changement de schéma avant la production. L'équipe utilise EF Core. Que mettre en place ?

Générer en CI un script idempotent (dotnet ef migrations script --idempotent), le publier comme artefact, mettre une approbation sur l'environment de production, et déployer ce script-là.

9. Après une migration de base réussie, la nouvelle version de l'API provoque des erreurs. Le chef de projet demande un retour arrière complet, base comprise. Quel conseil ?

Roll forward : revenir à l'API N-1 si elle supporte le nouveau schéma (c'est le but de la compatibilité N/N-1), et corriger l'API par un hotfix ; défaire la migration est risqué. Le point-in-time restore reste le dernier recours en cas de données abîmées.

10. Un canary sur AKS doit passer par 10 %, puis 20 %, avec dix minutes de surveillance à chaque palier, puis être promu automatiquement. Comment l'écrire dans Azure Pipelines ?

Un deployment job avec strategy: canary, increments: [10, 20], KubernetesManifest@1 avec action: $(strategy.action), strategy: $(strategy.name), percentage: $(strategy.increment) ; un postRouteTraffic avec Delay@1 (ou une vérification de santé) ; on: failure pour rejeter.


13. Pour aller plus loin#

  • Deployment Stamps : déployer une variante de blue-green stamp par stamp, en multi-région (pattern Deployment Stamps).
  • Blue-green de clusters AKS : guide d'architecture Microsoft, avec Application Gateway ou Front Door devant deux clusters.
  • Network Watcher rule impact analyzer : simuler l'effet d'un changement de NSG ou de règles AVNM avant de le déployer.
  • Azure Functions Flex Consumption n'a pas de deployment slots, mais une site update strategy RollingUpdate (siteUpdateStrategy.type) : instances vidées et remplacées par lots, sans coupure. Pas de canary ni de répartition du trafic, pas de bouton de retour arrière (on redéploie la version précédente) ; les changements doivent rester compatibles avec la version précédente (Site update strategies in Flex Consumption).

14. Fiche à retenir#

  • Déployer ≠ exposer : stratégie de déploiement (où tourne le code) + feature flags (qui le voit).
  • Blue-green = deux environnements, bascule ; canary = part du trafic ; ring = groupes d'utilisateurs ; rolling = lots d'instances.
  • Progressive exposure : bake time en heures ou jours, arrêt au premier signal négatif.
  • v1 et v2 cohabitent : compatibilité N / N-1 de l'API et du schéma.
  • Ordre : infra → base → API → front → smoke tests ; dependsOn (Azure Pipelines), needs (GitHub Actions).
  • Slots : Standard, Premium, Isolated ; production toujours en cible ; swap with preview ; auto swap pas sur Linux.
  • Non échangés : custom domains, certificats non publics, scale, IP restrictions, Always On, managed identities, VNet integration.
  • --slot-settings = réglage qui reste dans le slot ; az webapp traffic-routing set = canary sur slot.
  • VMSS : Automatic (dev/test), Manual, Rolling (health probe requis, MaxSurge).
  • Deployment job : runOnce, rolling (VM seulement), canary ; pas de checkout auto ; hooks preDeploy → deploy → routeTraffic → postRouteTraffic → on success/failure.
  • Hotfix (Release Flow) : corriger dans main, cherry-pick vers la release, déployer par rings ; accélérer sans supprimer les gates.
  • Résilience : roll back, roll forward, redéployer l'infra, éteindre le flag, point-in-time restore.
  • App Configuration : Switch, Rollout, Experiment ; filtres Time window, Targeting, Percentage ; requirement_type Any (défaut) / All.
  • Variants : allocation user → group → percentile ; DefaultWhenDisabled = kill switch.
  • Base : DACPAC (SqlAzureDacpacDeployment@1 Windows ou SqlPackage), EF migration bundle, script idempotent approuvé ; roll forward après migration.

Références#

Toutes lues le 21/10/2026 :

Sur cette page
Échap

Tape au moins 2 lettres. Plusieurs mots : tous doivent apparaître.