演習 - ブルーグリーン デプロイ パターンを実装する

完了

Azure Pipelines を使用してマルチステージ パイプラインを作成する」では、"開発"、"テスト"、"ステージング" の各ステージで Azure App Service に Web アプリケーションをデプロイする基本のデプロイ パイプラインを構築しました。

ここでは、"ステージング" 中に "ブルーグリーン" デプロイ パターンを適用してそのワークフローに追加します。

これを行うには、次の手順を実行します。

  • "ステージング" に対応する App Service インスタンスにデプロイ スロットを追加します。
  • パイプラインに、デプロイ スロットをスワップするタスクを追加します。

デプロイ スロットの追加

ここでは、"ステージング" に対応する App Service インスタンスにデプロイ スロットを追加します。

既定では、すべての App Service インスタンスで、production という名前の既定のスロットが提供されます。 前のセクションでパイプラインを設定したときに、production スロットにデプロイしました。

1 つの App Service インスタンスに、複数のスロットを設けることができます。 ここでは、"ステージング" に対応する App Service インスタンスに 2 つ目のデプロイ スロットを追加します。 このデプロイ スロットには swap という名前が付けられます。

スロットを追加するには、以下の操作を行います。

  1. Azure Portal にアクセスしてサインインします。

  2. メニューで、[Cloud Shell] を選択します。 プロンプトが表示されたら、[Bash] エクスペリエンスを選択します。

  3. 次のコマンドを実行して、"ステージング" に対応する App Service インスタンスの名前を取得し、その結果を、staging という名前の Bash 変数に格納します。

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

    --query 引数では、JSON 用のクエリ言語である JMESPath を使用します。 この引数により、name フィールドに "tailspin-space-game-web-staging" が含まれている App Service インスタンスが選択されます。

  4. staging 変数を出力して、正しい名前を取得したことを 確認します。

    echo $staging
    

    この場合の出力例を以下に示します。

    tailspin-space-game-web-staging-1234
    
  5. 次のコマンドを実行して、ステージング環境に swap という名前のスロットを追加します。

    az webapp deployment slot create \
      --name $staging \
      --resource-group tailspin-space-game-rg \
      --slot swap
    
  6. 次のコマンドを実行して、デプロイ スロットのホスト名を一覧表示します。

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

    結果はこの出力のようになります。

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

    後のために、このホスト名をメモしておきます。

  7. 省略可能な手順として、ブラウザーでサイトにアクセスします。 このスロットにはまだコードをデプロイしていないため、既定のホーム ページが表示されます。

    Screenshot of the default home page in Azure App Service.

既定では、インターネットからデプロイ スロットにアクセスできます。 実際には、インターネットからはルーティングできないものの、あなたのチームのみがアクセスできるネットワーク内に swap スロットを配置する Azure 仮想ネットワークを構成できます。 production スロットは、インターネットから到達可能なままになります。

ステージングでデプロイ スロットをスワップする

ここでは、AzureAppServiceManage@0 タスクを使用して "ステージング" 環境のデプロイ スロットをスワップします。

このタスクを使用して、スロットの起動、停止、削除を行うこともできます。 または、それを使用して、サイト拡張機能をインストールしたり、App Service で継続的監視を有効にしたりすることができます。

  1. Visual Studio Code で、下記のコードを使用して azure-pipelines.yml を変更します。

    ヒント

    ファイル全体を置き換えることも、強調表示されている部分のみを更新することもできます。

    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'
    

    以下の変更に注目してください。

    • AzureWebApp@1 タスクでは、以下の値を指定するようになっています。
      • deployToSlotOrASEtrue に設定すると、既存のデプロイ スロットにデプロイします。
      • resourceGroupName ではリソース グループの名前を指定しています。 この値は、deployToSlotOrASEtrue であるときには必須です。
      • slotName ではデプロイ スロットの名前を指定しています。 ここでは、swap という名前のスロットにデプロイします。
    • 新しいタスクの AzureAppServiceManage@0 では、デプロイ スロットをスワップしています。
      • sourceSlottargetSlot では、スワップするスロットを指定しています。
      • action では、実行するアクションを指定しています。 このタスクを使用して、スロットの起動、停止、削除を行えることを思い出してください。 ここで、"Swap Slots" によって、ソースとターゲットのスロットをスワップするように指定しています。

    この構成は、常に swap スロットにデプロイされます。 次に、production スロットと swap スロットがスワップされます。 このスワップ プロセスにより、production がより新しいデプロイを指し示すようになります。

  2. 統合ターミナルで、azure-pipelines.yml をインデックスに追加します。 変更をコミットしてから、GitHub にブランチをプッシュします。

    ヒント

    これらの Git コマンドを実行する前に、azure-pipelines.yml を保存します。

    git add azure-pipelines.yml
    git commit -m "Swap deployment slots"
    git push origin blue-green
    
  3. Azure Pipelines で、各ステップを通してビルドをトレースします。

注意

次のエラー ...'staging' slot did not respond to http ping. (CODE: 417) が発生した場合、アプリ サービスを再起動してみてください。 問題が解決しない場合、スロットの自動スワップをリセットします。

  1. 省略可能な手順として、ブラウザーで、各ステージに対応する URL にアクセスします。

    Web サイトにはまだ変更を加えていませんが、Space Game Web サイトが各 App Service 環境に正常にデプロイされたことがわかります。

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