Ćwiczenie — dodawanie wielu środowisk do potoku

Ukończone

Teraz możesz zaktualizować potok w celu wdrożenia w środowiskach testowych i produkcyjnych. W tej lekcji zaktualizujesz potok, aby używały szablonów, aby umożliwić ponowne użycie etapów w środowiskach.

Podczas tego procesu wykonasz następujące czynności:

  • Dodaj szablon potoku dla etapu lint.
  • Dodaj szablon potoku, który definiuje etapy wymagane do wdrożenia w dowolnym środowisku.
  • Zaktualizuj potok, aby używał szablonów.
  • Uruchom potok i wyświetl wyniki.

Dodawanie szablonu potoku dla etapu lint

Etap lint odbywa się tylko raz podczas uruchamiania potoku, niezależnie od tego, ile środowisk potok wdraża. W związku z tym nie trzeba używać szablonów na etapie lint. Jednak aby plik definicji potoku był prosty i łatwy do odczytania, decydujesz się zdefiniować etap lint w szablonie.

  1. W programie Visual Studio Code utwórz nowy folder o nazwie pipeline-templates w folderze deploy .

  2. Utwórz nowy plik w folderze pipeline-templates o nazwie lint.yml.

    Zrzut ekranu eksploratora programu Visual Studio Code z folderem pipeline-templates i plikiem lint dot Y M L.

  3. Wklej następującą definicję szablonu potoku do pliku:

    jobs:
    - job: LintCode
      displayName: Lint code
      steps:
        - script: |
            az bicep build --file deploy/main.bicep
          name: LintBicepCode
          displayName: Run Bicep linter
    

    Etap lint jest taki sam jak etap lint już w potoku, ale teraz znajduje się w osobnym pliku szablonu potoku.

  4. Zapisz zmiany i zamknij plik.

Dodawanie szablonu potoku do wdrożenia

Utwórz szablon potoku, który definiuje wszystkie etapy wymagane do wdrożenia każdego środowiska. Parametry szablonu służą do określania ustawień, które mogą się różnić między środowiskami.

  1. Utwórz nowy plik w folderze pipeline-templates o nazwie deploy.yml.

    Zrzut ekranu eksploratora programu Visual Studio Code z folderem pipeline-templates i plikiem deploy dot YML.

    Ten plik reprezentuje wszystkie działania wdrażania, które są uruchamiane dla każdego środowiska.

  2. Wklej następujące parametry szablonu potoku do pliku:

    parameters:
    - name: environmentType
      type: string
    - name: resourceGroupName
      type: string
    - name: serviceConnectionName
      type: string
    - name: deploymentDefaultLocation
      type: string
      default: westus3
    

    Uwaga

    Gdy zaczniesz pracować z plikiem YAML w programie Visual Studio Code, mogą pojawić się czerwone ziewione wiersze informujące o problemie. Dzieje się tak, ponieważ rozszerzenie programu Visual Studio Code dla plików YAML czasami niepoprawnie odgaduje schemat pliku.

    Możesz zignorować problemy zgłaszane przez rozszerzenie. Jeśli wolisz, możesz dodać następujący kod na początku pliku, aby pominąć odgadywanie rozszerzenia:

    # yaml-language-server: $schema=./deploy.yml
    
  3. Poniżej parametrów wklej definicję etapu weryfikacji:

    stages:
    
    - ${{ if ne(parameters.environmentType, 'Production') }}:
      - stage: Validate_${{parameters.environmentType}}
        displayName: Validate (${{parameters.environmentType}} Environment)
        jobs:
        - job: ValidateBicepCode
          displayName: Validate Bicep code
          steps:
            - task: AzureResourceManagerTemplateDeployment@3
              name: RunPreflightValidation
              displayName: Run preflight validation
              inputs:
                connectedServiceName: ${{parameters.serviceConnectionName}}
                location: ${{parameters.deploymentDefaultLocation}}
                deploymentMode: Validation
                resourceGroupName: ${{parameters.resourceGroupName}}
                csmFile: deploy/main.bicep
                overrideParameters: >
                  -environmentType ${{parameters.environmentType}}
    

    Zwróć uwagę, że warunek jest stosowany do tego etapu. Działa tylko w środowiskach nieprodukcyjnych.

    Zwróć również uwagę, że identyfikator etapu zawiera wartość parametru environmentType . Ten parametr zapewnia, że każdy etap w potoku ma unikatowy identyfikator. Etap zawiera displayName również właściwość , aby utworzyć dobrze sformatowaną nazwę do odczytania.

  4. Poniżej etapu weryfikacji wklej definicję etapu podglądu:

    - ${{ if eq(parameters.environmentType, 'Production') }}:
      - stage: Preview_${{parameters.environmentType}}
        displayName: Preview (${{parameters.environmentType}} Environment)
        jobs:
        - job: PreviewAzureChanges
          displayName: Preview Azure changes
          steps:
            - task: AzureCLI@2
              name: RunWhatIf
              displayName: Run what-if
              inputs:
                azureSubscription: ${{parameters.serviceConnectionName}}
                scriptType: 'bash'
                scriptLocation: 'inlineScript'
                inlineScript: |
                  az deployment group what-if \
                    --resource-group ${{parameters.resourceGroupName}} \
                    --template-file deploy/main.bicep \
                    --parameters environmentType=${{parameters.environmentType}}
    

    Zwróć uwagę, że ten etap ma również zastosowany warunek, ale jest przeciwieństwem warunku etapu weryfikacji. Etap podglądu jest uruchamiany tylko dla środowiska produkcyjnego.

  5. Poniżej etapu podglądu wklej definicję etapu wdrażania:

    - stage: Deploy_${{parameters.environmentType}}
      displayName: Deploy (${{parameters.environmentType}} Environment)
      jobs:
      - deployment: DeployWebsite
        displayName: Deploy website
        environment: ${{parameters.environmentType}}
        strategy:
          runOnce:
            deploy:
              steps:
                - checkout: self
    
                - task: AzureResourceManagerTemplateDeployment@3
                  name: DeployBicepFile
                  displayName: Deploy Bicep file
                  inputs:
                    connectedServiceName: ${{parameters.serviceConnectionName}}
                    deploymentName: $(Build.BuildNumber)
                    location: ${{parameters.deploymentDefaultLocation}}
                    resourceGroupName: ${{parameters.resourceGroupName}}
                    csmFile: deploy/main.bicep
                    overrideParameters: >
                      -environmentType ${{parameters.environmentType}}
                    deploymentOutputs: deploymentOutputs
    
                - bash: |
                    echo "##vso[task.setvariable variable=appServiceAppHostName;isOutput=true]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppHostName.value')"
                  name: SaveDeploymentOutputs
                  displayName: Save deployment outputs into variables
                  env:
                    DEPLOYMENT_OUTPUTS: $(deploymentOutputs)
    
  6. Poniżej etapu wdrażania wklej definicję etapu testu weryfikacyjnego kompilacji:

    - stage: SmokeTest_${{parameters.environmentType}}
      displayName: Smoke Test (${{parameters.environmentType}} Environment)
      jobs:
      - job: SmokeTest
        displayName: Smoke test
        variables:
          appServiceAppHostName: $[ stageDependencies.Deploy_${{parameters.environmentType}}.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ]
        steps:
          - task: PowerShell@2
            name: RunSmokeTests
            displayName: Run smoke tests
            inputs:
              targetType: inline
              script: |
                $container = New-PesterContainer `
                  -Path 'deploy/Website.Tests.ps1' `
                  -Data @{ HostName = '$(appServiceAppHostName)' }
                Invoke-Pester `
                  -Container $container `
                  -CI
    
          - task: PublishTestResults@2
            name: PublishTestResults
            displayName: Publish test results
            condition: always()
            inputs:
              testResultsFormat: NUnit
              testResultsFiles: 'testResults.xml'
    

    Zwróć uwagę, że appServiceAppHostName definicja zmiennej zawiera environmentType parametr, gdy odwołuje się do etapu, który opublikował nazwę hosta. Ten parametr zapewnia, że każdy etap testu weryfikacyjnego kompilacji jest uruchamiany w prawidłowym środowisku.

  7. Sprawdź, czy plik deploy.yml wygląda teraz jak w poniższym przykładzie:

    parameters:
    - name: environmentType
      type: string
    - name: resourceGroupName
      type: string
    - name: serviceConnectionName
      type: string
    - name: deploymentDefaultLocation
      type: string
      default: westus3
    
    stages:
    
    - ${{ if ne(parameters.environmentType, 'Production') }}:
      - stage: Validate_${{parameters.environmentType}}
        displayName: Validate (${{parameters.environmentType}} Environment)
        jobs:
        - job: ValidateBicepCode
          displayName: Validate Bicep code
          steps:
            - task: AzureResourceManagerTemplateDeployment@3
              name: RunPreflightValidation
              displayName: Run preflight validation
              inputs:
                connectedServiceName: ${{parameters.serviceConnectionName}}
                location: ${{parameters.deploymentDefaultLocation}}
                deploymentMode: Validation
                resourceGroupName: ${{parameters.resourceGroupName}}
                csmFile: deploy/main.bicep
                overrideParameters: >
                  -environmentType ${{parameters.environmentType}}
    
    - ${{ if eq(parameters.environmentType, 'Production') }}:
      - stage: Preview_${{parameters.environmentType}}
        displayName: Preview (${{parameters.environmentType}} Environment)
        jobs:
        - job: PreviewAzureChanges
          displayName: Preview Azure changes
          steps:
            - task: AzureCLI@2
              name: RunWhatIf
              displayName: Run what-if
              inputs:
                azureSubscription: ${{parameters.serviceConnectionName}}
                scriptType: 'bash'
                scriptLocation: 'inlineScript'
                inlineScript: |
                  az deployment group what-if \
                    --resource-group ${{parameters.resourceGroupName}} \
                    --template-file deploy/main.bicep \
                    --parameters environmentType=${{parameters.environmentType}}
    
    - stage: Deploy_${{parameters.environmentType}}
      displayName: Deploy (${{parameters.environmentType}} Environment)
      jobs:
      - deployment: DeployWebsite
        displayName: Deploy website
        environment: ${{parameters.environmentType}}
        strategy:
          runOnce:
            deploy:
              steps:
                - checkout: self
    
                - task: AzureResourceManagerTemplateDeployment@3
                  name: DeployBicepFile
                  displayName: Deploy Bicep file
                  inputs:
                    connectedServiceName: ${{parameters.serviceConnectionName}}
                    deploymentName: $(Build.BuildNumber)
                    location: ${{parameters.deploymentDefaultLocation}}
                    resourceGroupName: ${{parameters.resourceGroupName}}
                    csmFile: deploy/main.bicep
                    overrideParameters: >
                      -environmentType ${{parameters.environmentType}}
                    deploymentOutputs: deploymentOutputs
    
                - bash: |
                    echo "##vso[task.setvariable variable=appServiceAppHostName;isOutput=true]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppHostName.value')"
                  name: SaveDeploymentOutputs
                  displayName: Save deployment outputs into variables
                  env:
                    DEPLOYMENT_OUTPUTS: $(deploymentOutputs)
    
    - stage: SmokeTest_${{parameters.environmentType}}
      displayName: Smoke Test (${{parameters.environmentType}} Environment)
      jobs:
      - job: SmokeTest
        displayName: Smoke test
        variables:
          appServiceAppHostName: $[ stageDependencies.Deploy_${{parameters.environmentType}}.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ]
        steps:
          - task: PowerShell@2
            name: RunSmokeTests
            displayName: Run smoke tests
            inputs:
              targetType: inline
              script: |
                $container = New-PesterContainer `
                  -Path 'deploy/Website.Tests.ps1' `
                  -Data @{ HostName = '$(appServiceAppHostName)' }
                Invoke-Pester `
                  -Container $container `
                  -CI
    
          - task: PublishTestResults@2
            name: PublishTestResults
            displayName: Publish test results
            condition: always()
            inputs:
              testResultsFormat: NUnit
              testResultsFiles: 'testResults.xml'
    
  8. Zapisz zmiany w pliku.

Aktualizowanie definicji potoku w celu używania szablonów

  1. Otwórz plik azure-pipelines.yml.

  2. Zaktualizuj plik, aby używał nowych szablonów, zastępując zawartość następującym kodem:

    trigger:
      batch: true
      branches:
        include:
        - main
    
    pool:
      vmImage: ubuntu-latest
    
    stages:
    
    # Lint the Bicep file.
    - stage: Lint
      jobs: 
      - template: pipeline-templates/lint.yml
    
    # Deploy to the test environment.
    - template: pipeline-templates/deploy.yml
      parameters:
        environmentType: Test
        resourceGroupName: ToyWebsiteTest
        serviceConnectionName: ToyWebsiteTest
    
    # Deploy to the production environment.
    - template: pipeline-templates/deploy.yml
      parameters:
        environmentType: Production
        resourceGroupName: ToyWebsiteProduction
        serviceConnectionName: ToyWebsiteProduction
    

    Ten potok uruchamia etap lint raz. Następnie używa dwa razy pliku szablonu deploy.yml : raz na środowisko. Dzięki temu definicja potoku jest jasna i łatwa do zrozumienia. Ponadto komentarze pomagają wyjaśnić, co się dzieje.

  3. Zapisz zmiany.

  4. Zatwierdź i wypchnij zmiany do repozytorium Git, uruchamiając następujące polecenia w terminalu programu Visual Studio Code:

    git add .
    git commit -m "Add pipeline templates"
    git push
    

Wyświetlanie przebiegu potoku

  1. W przeglądarce przejdź do pozycji Potoki.

  2. Wybierz najnowszy przebieg potoku.

    Zwróć uwagę, że uruchomienie potoku pokazuje teraz wszystkie etapy zdefiniowane w pliku YAML. Może być konieczne przewinięcie w poziomie, aby wyświetlić je wszystkie.

    Zrzut ekranu przedstawiający etapy uruchamiania potoku w usłudze Azure Pipelines.

  3. Poczekaj na wstrzymanie potoku przed etapem Wdrażanie (środowisko produkcyjne). Osiągnięcie tego punktu przez potok może potrwać kilka minut.

    Zrzut ekranu usługi Azure Pipelines przedstawiający przebieg potoku wstrzymany do zatwierdzenia.

  4. Zatwierdź wdrożenie w środowisku produkcyjnym, wybierając przycisk Przejrzyj .

  5. Wybierz przycisk Zatwierdź.

    Zrzut ekranu przedstawiający interfejs usługi Azure DevOps przedstawiający stronę zatwierdzania potoku i przycisk Zatwierdź.

    Poczekaj na zakończenie działania potoku.

  6. Wybierz kartę Testy, aby wyświetlić wyniki testu z tego przebiegu potoku.

    Zwróć uwagę, że istnieją teraz cztery wyniki testu. Test weryfikacyjny kompilacji jest uruchamiany zarówno w środowiskach testowych, jak i produkcyjnych, dzięki czemu wyniki są widoczne dla obu zestawów testów.

    Zrzut ekranu usługi Azure Pipelines przedstawiający stronę testów przebiegu potoku z czterema wynikami testu.

  7. Wybierz pozycję Środowiska potoków>.

  8. Wybierz środowisko produkcyjne.

  9. Zwróć uwagę, że na ekranie szczegółów środowiska zostanie wyświetlone omówienie historii wdrożenia środowiska produkcyjnego.

    Zrzut ekranu usługi Azure Pipelines przedstawiający środowisko produkcyjne z historią wdrażania z pojedynczym wdrożeniem.

  10. Wybierz wdrożenie i wybierz kartę Zmiany .

    Zwróć uwagę, że karta Zmiany zawiera listę zatwierdzeń uwzględnionych we wdrożeniu. Te informacje ułatwiają sprawdzenie dokładnie tego, co zmieniło się w środowisku w czasie.

    Zrzut ekranu usługi Azure Pipelines przedstawiający szczegóły wdrożenia środowiska produkcyjnego z listą zatwierdzeń.

  11. W przeglądarce przejdź do witryny Azure Portal.

  12. Przejdź do grupy zasobów ToyWebsiteProduction .

  13. Na liście zasobów otwórz aplikację usługi aplikacja systemu Azure Service.

    Zrzut ekranu witryny Azure Portal przedstawiający produkcyjną aplikację App Service i szczegóły jednostki SKU planu usługi App Service.

    Zwróć uwagę, że typ planu usługi App Service to S1.

  14. Przejdź do aplikacji App Service w grupie zasobów ToyWebsiteTest .

    Zwróć uwagę, że typ planu usługi App Service to F1. Te dwa środowiska używają różnych ustawień, zgodnie z definicją w pliku Bicep.