Cvičení – implementace vzoru nasazení modro-zeleného modelu

Dokončeno

V části Vytvoření kanálu s více fázemi pomocí Azure Pipelines jste vytvořili základní kanál nasazení, který nasadí webovou aplikaci do služby Azure App Service v těchto fázích: Vývoj, testování a příprava.

V rámci tohoto pracovního postupu přidáte vzor nasazení modro-zeleného během přípravné fáze.

Pro dosažení toho můžete provést následující:

  • Přidejte slot nasazení do instance služby App Service, která odpovídá fázi nasazení přípravy.
  • Přidejte do pipeline úlohu pro prohození slotů nasazení.

Přidání slotu nasazení

Tady přidáte nasazovací slot do instance služby App Service, která odpovídá přípravné fázi.

Ve výchozím nastavení poskytuje každá instance služby App Service výchozí slot pojmenovaný produkční. Při nastavování kanálu (pipeline) v předchozí části jste nasadili na slot v produkčním prostředí.

Instance služby App Service může mít více slotů. Tady přidáte druhý slot pro nasazení v instanci služby App Service, který odpovídá Staging. Slot nasazení má název swapu.

Přidání slotu:

  1. Přejděte na web Azure Portal a přihlaste se.

  2. V nabídce vyberte Cloud Shell. Až se zobrazí výzva, vyberte prostředí Bash.

  3. Spuštěním následujícího příkazu získejte název instance služby App Service, která odpovídá přípravnému prostředí , a uložte výsledek do proměnné Bash s názvem staging.

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

    Argument --query používá JMESPath, což je dotazovací jazyk JSON. Argument vybere instanci služby App Service, jejíž pole name obsahuje "tailspin-space-game-web-staging".

  4. Vytiskněte proměnnou staging, abyste ověřili, že získáte správný název.

    echo $staging
    

    Tady je příklad výstupu:

    tailspin-space-game-web-staging-1234
    
  5. Spuštěním následujícího příkazu přidejte slot pojmenovaný swap do přípravného prostředí.

    az webapp deployment slot create \
      --name $staging \
      --resource-group tailspin-space-game-rg \
      --slot swap
    
  6. Spusťte tento příkaz pro vypsání názvu hostitele slotu nasazení.

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

    Výsledek se podobá tomuto výstupu:

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

    Poznamenejte si tento název hostitele pro pozdější použití.

  7. Jako volitelný krok přejděte na svůj web v prohlížeči. Zobrazí se výchozí domovská stránka, protože jste ještě nenasadili kód do tohoto slotu.

    Snímek obrazovky s výchozí domovskou stránkou ve službě Azure App Service

Ve výchozím nastavení je slot nasazení přístupný z internetu. V praxi byste mohli nakonfigurovat virtuální síť Azure, která umístí váš slot pro prohození do sítě nepřístupné z internetu, ale dostupné pouze vašemu týmu. Váš produkční slot by zůstal dostupný z internetu.

Přepněte sloty nasazení v přípravě

Tady použijete úlohu AzureAppServiceManage@0 k prohození slotů nasazení v přípravném prostředí.

Tento úkol můžete použít také ke spuštění, zastavení nebo odstranění slotu. Nebo ho můžete použít k instalaci rozšíření webu nebo k povolení průběžného monitorování ve službě App Service.

  1. V editoru Visual Studio Code upravte azure-pipelines.yml pomocí tohoto kódu:

    Návod

    Celý soubor můžete nahradit nebo jenom aktualizovat zvýrazněnou část.

    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'
    

    Všimněte si těchto změn:

    • Úloha AzureWebApp@1 teď určuje tyto hodnoty:
      • deployToSlotOrASE, je-li nastavena na true, nasadí do existujícího nasazovacího slotu.
      • resourceGroupName určuje název skupiny prostředků. Tato hodnota se vyžaduje, pokud je deployToSlotOrASEtrue.
      • slotName určuje název slotu nasazení. Zde nasadíte do slotu jménem swap.
    • Nová úloha, AzureAppServiceManage@0, prohodí sloty nasazení.
      • sourceSlot a targetSlot specifikují sloty k prohození.
      • action určuje akci, která se má provést. Vzpomeňte si, že tento úkol můžete použít ke spuštění, zastavení nebo odstranění slotu. Zde "Prohození slotů" určuje prohození zdrojových a cílových slotů.

    Tato konfigurace se vždy nasadí do slotu prohození. Potom prohodí sloty produkce a . Proces výměny zajistí, že produktivní odkazuje na novější nasazení.

  2. V integrovaném terminálu přidejte do indexu azure-pipelines.yml . Potvrďte změny a pak pushněte větev na GitHub.

    Návod

    Před spuštěním těchto příkazů Git uložte azure-pipelines.yml .

    git add azure-pipelines.yml
    git commit -m "Swap deployment slots"
    git push origin blue-green
    
  3. V Azure Pipelines můžete sledovat sestavení na každém kroku.

Poznámka

Pokud narazíte na následující chybu ...'staging' slot did not respond to http ping. (CODE: 417) , zkuste restartovat službu App Service. Pokud problém přetrvává, resetujte automatické přepínání pro váš slot.

  1. Jako volitelný krok v prohlížeči přejděte na adresu URL odpovídající každé fázi.

    I když jste ještě neprovedli změny na webu, uvidíte, že se web Space Game úspěšně nasadil do každého prostředí služby App Service.

    Snímek obrazovky prohlížeče, který zobrazuje web Space Game v vývojovém prostředí