練習 - 實作藍綠部署模式

已完成

使用 Azure Pipelines 建立多階段管線中,您建立了一個基本部署管線,可將 Web 應用程式部署至在以下這些階段中的 Azure App Service:「開發」、「測試」和「預備」

在這裡,您透過在「預備」期間套用「藍綠」部署模式,新增該工作流程。

若要這樣做,您可以:

  • 將部署位置新增至對應至「預備」的 App Service 執行個體。
  • 將工作新增至管線以交換部署位置。

新增部署位置

在此,您將部署位置新增至對應至「預備」的 App Service 執行個體。

根據預設,每個 App Service 執行個體都會提供名為「生產」的預設位置。 當您在上一節中設定管線時,會部署到「生產」位置。

App Service 執行個體可以有多個位置。 在此,您將第二個部署位置新增至對應至「預備」的 App Service 執行個體。 部署位置名稱為「交換」

若要新增位置:

  1. 請前往 Azure 入口網站並登入。

  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 引數會使用 JMESPath,其為 JSON 的查詢語言。 引數會選取其 name 欄位包含 "tailspin-space-game-web-staging" 的 App Service 執行個體。

  4. 列印 staging 變數以確認您取得正確的名稱。

    echo $staging
    

    以下是輸出的範例:

    tailspin-space-game-web-staging-1234
    
  5. 執行下列命令,將名為「交換」的位置新增至您的預備環境。

    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.

根據預設,部署位置可從網際網路存取。 在實務上,您可以設定 Azure 虛擬網路,將您的「交換」位置放在非網際網路可路由傳送的網路中,而且只有您和您的小組可以存取。 您的「生產」位置仍可從網際網路連線。

在「預備」環境中交換部署位置

在此,您使用 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 工作現在會指定下列值:
      • deployToSlotOrASE,當設為 true 時,會部署到現有的部署位置。
      • resourceGroupName 會指定資源群組的名稱。 當 deployToSlotOrASEtrue 時,此值為必要。
      • slotName 會指定部署位置的名稱。 在這裡您部署至名為「交換」的位置。
    • 新的工作 AzureAppServiceManage@0 會交換部署位置。
      • sourceSlottargetSlot 指定要交換的位置。
      • action 指定要執行的動作。 回想一下,您可以使用此工作來啟動、停止或刪除位置。 在這裡,指定「交換位置」來交換來源和目標位置。

    此組態一律會部署至「交換」位置。 然後,它會交換「生產」和「交換」位置。 交換程序可確保「生產」指向較新的部署。

  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。

    雖然您尚未對網站進行變更,但您會看到 Space Game 網站已成功部署至每個 App Service 環境。

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