Exercice - Implémenter le modèle de déploiement bleu-vert

Effectué

Dans Créer un pipeline multiphase à l’aide d’Azure Pipelines, vous avez créé un pipeline de déploiement de base qui déploie une application web sur Azure App Service au cours des phases suivantes : Développement, Test et Préproduction.

Ici, vous complétez ce workflow en appliquant le modèle de déploiement bleu-vert durant la phase Préproduction.

Pour cela, vous devez :

  • Ajoutez un emplacement de déploiement à l’instance d’App Service qui correspond à Préproduction.
  • Ajoutez une tâche au pipeline pour échanger les emplacements de déploiement.

Ajouter un emplacement de déploiement

Ici, vous ajoutez un emplacement de déploiement à l’instance d’App Service qui correspond à Préproduction.

Par défaut, chaque instance d’App Service fournit un emplacement par défaut nommé production. Vous avez effectué un déploiement sur l’emplacement production quand vous avez configuré le pipeline au cours de la section précédente.

Une instance d’App Service peut avoir plusieurs emplacements. Ici, vous ajoutez un second emplacement de déploiement à l’instance d’App Service qui correspond à Préproduction. L’emplacement de déploiement se nomme swap.

Pour ajouter l’emplacement :

  1. Accédez au portail Azure et connectez-vous.

  2. Dans le menu, sélectionnez Cloud Shell. Quand vous y êtes invité, sélectionnez l’expérience Bash.

  3. Exécutez la commande suivante pour obtenir le nom de l’instance d’App Service qui correspond à Préproduction ainsi que pour stocker le résultat dans une variable Bash nommée staging.

    staging=$(az webapp list \
      --resource-group tailspin-space-game-rg \
      --query "[?contains(@.name, 'tailspin-space-game-web-staging')].{name: name}" \
      --output tsv)
    

    L’argument --query utilise JMESPath, qui est un langage de requête pour JSON. L’argument sélectionne l’instance d’App Service dont le champ name contient « tailspin-space-game-web-staging ».

  4. Affichez la variable staging pour vérifier que vous obtenez le nom approprié.

    echo $staging
    

    Voici un exemple de sortie :

    tailspin-space-game-web-staging-1234
    
  5. Exécutez la commande suivante pour ajouter un emplacement nommé swap à votre environnement de préproduction.

    az webapp deployment slot create \
      --name $staging \
      --resource-group tailspin-space-game-rg \
      --slot swap
    
  6. Exécutez la commande suivante pour lister le nom d’hôte de votre emplacement de déploiement.

    az webapp deployment slot list \
        --name $staging \
        --resource-group tailspin-space-game-rg \
        --query [].hostNames \
        --output tsv
    

    Le résultat ressemble à ce qui suit :

    tailspin-space-game-web-staging-25391-swap.azurewebsites.net
    

    Notez ce nom d’hôte, car vous en aurez besoin plus tard.

  7. En guise d’étape facultative, accédez à votre site dans un navigateur. La page d’accueil par défaut s’affiche, car vous n’avez pas encore déployé votre code sur cet emplacement.

    Screenshot of the default home page in Azure App Service.

Par défaut, un emplacement de déploiement est accessible depuis Internet. En pratique, vous pouvez configurer un réseau virtuel Azure qui place votre emplacement swap dans un réseau non routable à partir d’Internet mais accessible uniquement à votre équipe. Votre emplacement de production reste accessible depuis Internet.

Échanger les emplacements de déploiement dans la phase de préproduction

Ici, vous utilisez la tâche AzureAppServiceManage@0 pour échanger des emplacements de déploiement dans votre environnement intermédiaire.

Vous pouvez également utiliser cette tâche pour démarrer, arrêter ou supprimer un emplacement. Vous pouvez également l’utiliser pour installer des extensions de site ou pour activer la supervision continue sur App Service.

  1. Dans Visual Studio Code, modifiez azure-pipelines.yml à l’aide du code suivant :

    Conseil

    Vous pouvez remplacer le fichier entier ou simplement mettre à jour la partie mise en évidence.

    trigger:
    - '*'
    
    variables:
      buildConfiguration: 'Release'
    
    stages:
    - stage: 'Build'
      displayName: 'Build the web application'
      jobs: 
      - job: 'Build'
        displayName: 'Build job'
        pool:
          vmImage: 'ubuntu-20.04'
          demands:
          - npm
    
        variables:
          wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
          dotnetSdkVersion: '6.x'
    
        steps:
        - task: UseDotNet@2
          displayName: 'Use .NET SDK $(dotnetSdkVersion)'
          inputs:
            version: '$(dotnetSdkVersion)'
    
        - task: Npm@1
          displayName: 'Run npm install'
          inputs:
            verbose: false
    
        - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
          displayName: 'Compile Sass assets'
    
        - task: gulp@1
          displayName: 'Run gulp tasks'
    
        - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
          displayName: 'Write build info'
          workingDirectory: $(wwwrootDir)
    
        - task: DotNetCoreCLI@2
          displayName: 'Restore project dependencies'
          inputs:
            command: 'restore'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Build the project - $(buildConfiguration)'
          inputs:
            command: 'build'
            arguments: '--no-restore --configuration $(buildConfiguration)'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Publish the project - $(buildConfiguration)'
          inputs:
            command: 'publish'
            projects: '**/*.csproj'
            publishWebProjects: false
            arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
            zipAfterPublish: true
    
        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: drop
    
    - stage: 'Dev'
      displayName: 'Deploy to the dev environment'
      dependsOn: Build
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: dev
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  appName: '$(WebAppNameDev)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    
    - stage: 'Test'
      displayName: 'Deploy to the test environment'
      dependsOn: Dev
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: test
        variables:
        - group: 'Release'
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  appName: '$(WebAppNameTest)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    
    - stage: 'Staging'
      displayName: 'Deploy to the staging environment'
      dependsOn: Test
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: staging
        variables:
        - group: 'Release'
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  deployToSlotOrASE: 'true'
                  resourceGroupName: 'tailspin-space-game-rg'
                  slotName: 'swap'
                  appName: '$(WebAppNameStaging)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
              - task: AzureAppServiceManage@0
                displayName: 'Swap deployment slots'
                inputs:
                  azureSubscription: 'Resource Manager - Tailspin - Space Game'
                  resourceGroupName: 'tailspin-space-game-rg'
                  webAppName: '$(WebAppNameStaging)'
                  sourceSlot: 'swap'
                  targetSlot: 'production'
                  action: 'Swap Slots'
    

    Notez les changements suivants :

    • La tâche AzureWebApp@1 spécifie désormais les valeurs suivantes :
      • deployToSlotOrASE, quand il a la valeur true, se déploie sur un emplacement de déploiement existant.
      • resourceGroupName spécifie le nom du groupe de ressources. Cette valeur est obligatoire quand deployToSlotOrASE est true.
      • slotName spécifie le nom de l’emplacement de déploiement. Ici, vous effectuez un déploiement sur l’emplacement nommé swap.
    • La nouvelle tâche, AzureAppServiceManage@0, échange les emplacements de déploiement.
      • sourceSlot et targetSlot spécifient les emplacements à permuter.
      • action spécifie l’action à entreprendre. Rappelez-vous que vous pouvez utiliser cette tâche pour démarrer, arrêter ou supprimer un emplacement. Ici, « Échanger les emplacements » signifie échanger les emplacements source et cible.

    Cette configuration correspond toujours à un déploiement sur l’emplacement swap. Elle entraîne ensuite l’échange des emplacements production et swap. Le processus d’échange vérifie que production pointe vers le déploiement le plus récent.

  2. Dans le terminal intégré, ajoutez azure-pipelines.yml à l’index. Commitez les changements, puis poussez la branche vers GitHub.

    Conseil

    Enregistrez azure-pipelines.yml avant d’exécuter ces commandes Git.

    git add azure-pipelines.yml
    git commit -m "Swap deployment slots"
    git push origin blue-green
    
  3. Dans Azure Pipelines, suivez la build tout au long de chacune des étapes.

Notes

Si vous rencontrez l’erreur ...'staging' slot did not respond to http ping. (CODE: 417), essayez de redémarrer votre service d’application. Si le problème persiste, réinitialisez l’échange automatique pour votre emplacement.

  1. En guise d’étape facultative, dans un navigateur, accédez à l’URL qui correspond à chaque phase.

    Bien que vous n’ayez pas encore apporté de changements au site web, vous voyez que le site web Space Game a été correctement déployé sur chaque environnement App Service.

    Screenshot of a browser that shows the Space Game website in the Dev environment.