Övning – Lägga till flera miljöer i pipelinen

Slutförd

Nu är du redo att uppdatera pipelinen så att den distribueras till både test- och produktionsmiljöerna. I den här lektionen uppdaterar du pipelinen så att den använder mallar så att du kan återanvända stegen i miljöerna.

Under processen gör du följande:

  • Lägg till en pipelinemall för lint-fasen.
  • Lägg till en pipelinemall som definierar de steg som krävs för att distribuera till valfri miljö.
  • Uppdatera pipelinen så att den använder mallarna.
  • Kör pipelinen och visa resultatet.

Lägga till en pipelinemall för lintsteget

Lintsteget sker bara en gång under pipelinekörningen, oavsett hur många miljöer pipelinen distribuerar till. Därför behöver du inte använda mallar för lint-fasen. Men för att hålla huvuddefinitionsfilen för pipelinen enkel och lättläst bestämmer du dig för att definiera lintsteget i en mall.

  1. I Visual Studio Code skapar du en ny mapp med namnet pipeline-templates i distributionsmappen.

  2. Skapa en ny fil i mappen pipeline-templates med namnet lint.yml.

    Skärmbild av Visual Studio Code Explorer med mappen pipeline-templates och lint dot Y M L-filen.

  3. Klistra in följande definition av pipelinemallen i filen:

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

    Lint-fasen är samma som lint-fasen som redan finns i pipelinen, men nu finns den i en separat pipelinemallfil.

  4. Spara ändringarna och stäng filen.

Lägga till en pipelinemall för distribution

Skapa en pipelinemall som definierar alla steg som krävs för att distribuera var och en av dina miljöer. Du använder mallparametrar för att ange de inställningar som kan skilja sig åt mellan miljöer.

  1. Skapa en ny fil i mappen pipeline-templates med namnet deploy.yml.

    Skärmbild av Visual Studio Code Explorer med mappen pipeline-templates och YML-filen deploy dot.

    Den här filen representerar alla distributionsaktiviteter som körs för var och en av dina miljöer.

  2. Klistra in följande pipelinemallparametrar i filen:

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

    Kommentar

    När du börjar arbeta med YAML-filen i Visual Studio Code kan du se några röda vågiga rader som säger att det finns ett problem. Det beror på att Visual Studio Code-tillägget för YAML-filer ibland felaktigt gissar filens schema.

    Du kan ignorera de problem som tillägget rapporterar. Eller om du vill kan du lägga till följande kod överst i filen för att utelämna tilläggets gissning:

    # yaml-language-server: $schema=./deploy.yml
    
  3. Under parametrarna klistrar du in definitionen av valideringssteget:

    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}}
    

    Observera att ett villkor tillämpas på den här fasen. Den körs endast för icke-produktionsmiljöer.

    Observera också att stegidentifieraren innehåller värdet för parametern environmentType . Den här parametern säkerställer att varje steg i pipelinen har en unik identifierare. Fasen har också en displayName egenskap för att skapa ett välformaterat namn som du kan läsa.

  4. Under valideringssteget klistrar du in definitionen av förhandsversionssteget:

    - ${{ 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}}
    

    Observera att det här steget också har ett villkor tillämpat, men det är motsatsen till valideringsstegets villkor. Förhandsversionsfasen körs endast för produktionsmiljön.

  5. Under förhandsgranskningssteget klistrar du in definitionen av distributionssteget:

    - 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. Under distributionssteget klistrar du in definitionen av rökteststeget:

    - 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'
    

    Observera att variabeldefinitionen appServiceAppHostName innehåller parametern environmentType när den refererar till den fas som publicerade värdnamnet. Den här parametern säkerställer att varje rökteststeg körs mot rätt miljö.

  7. Kontrollera att filen deploy.yml nu ser ut som i följande exempel:

    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. Spara ändringarna i filen.

Uppdatera pipelinedefinitionen så att den använder mallarna

  1. Öppna filen azure-pipelines.yml.

  2. Uppdatera filen så att den använder de nya mallarna genom att ersätta innehållet med följande kod:

    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
    

    Den här pipelinen kör lintsteget en gång. Sedan används deploy.yml-mallfilen två gånger: en gång per miljö. Detta håller pipelinedefinitionen tydlig och lätt att förstå. Kommentarerna hjälper också till att förklara vad som händer.

  3. Spara dina ändringar.

  4. Checka in och skicka ändringarna till Git-lagringsplatsen genom att köra följande kommandon i Visual Studio Code-terminalen:

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

Visa pipelinekörningen

  1. Gå till Pipelines i webbläsaren.

  2. Välj den senaste körningen av din pipeline.

    Observera att pipelinekörningen nu visar alla steg som du definierade i YAML-filen. Du kan behöva rulla vågrätt för att se alla.

    Skärmbild av Azure Pipelines som visar pipelinekörningsstegen.

  3. Vänta tills pipelinen pausas innan fasen Distribuera (produktionsmiljö). Det kan ta några minuter innan pipelinen når den här punkten.

    Skärmbild av Azure Pipelines som visar att pipelinekörningen har pausats för godkännande.

  4. Godkänn distributionen till produktionsmiljön genom att välja knappen Granska .

  5. Välj knappen Godkänn.

    Skärmbild av Azure DevOps-gränssnittet som visar sidan för godkännande av pipeline och knappen Godkänn.

    Vänta tills pipelinen har körts.

  6. Välj fliken Tester för att visa testresultaten från den här pipelinekörningen.

    Observera att det nu finns fyra testresultat. Röktestet körs i både test- och produktionsmiljöerna, så du ser resultatet för båda testuppsättningarna.

    Skärmbild av Azure Pipelines som visar sidan för pipelinekörningstester med fyra testresultat.

  7. Välj Pipelines-miljöer>.

  8. Välj produktionsmiljön.

  9. Observera att på skärmen miljöinformation visas en översikt över produktionsmiljöns distributionshistorik.

    Skärmbild av Azure Pipelines som visar produktionsmiljön med distributionshistoriken som visar en enda distribution.

  10. Välj distributionen och välj fliken Ändringar .

    Observera att fliken Ändringar visar listan över incheckningar som ingår i distributionen. Den här informationen hjälper dig att se exakt vad som har ändrats i din miljö över tid.

    Skärmbild av Azure Pipelines som visar produktionsmiljöns distributionsinformation med en lista över incheckningar.

  11. I en webbläsare går du till Azure-portalen.

  12. Gå till resursgruppen ToyWebsiteProduction .

  13. Öppna Azure App Service-appen i listan över resurser.

    Skärmbild av Azure Portal som visar apptjänstappen för produktion och SKU-information för App Service-plan.

    Observera att typen av App Service-plan är S1.

  14. Gå till App Service-appen i resursgruppen ToyWebsiteTest .

    Observera att typen av App Service-plan är F1. De två miljöerna använder olika inställningar, som du definierade i Bicep-filen.