Delen via


Uitroltaken

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020

Belangrijk

  • Namen van taken en fasen kunnen geen trefwoorden bevatten (bijvoorbeeld: deployment).
  • Elke taak in een fase moet een unieke naam hebben.

In YAML-pijplijnen kunt u uw implementatiestappen beter in een speciaal type taak plaatsen, een zogenaamde implementatietaak. Een implementatietaak is een verzameling stappen die opeenvolgend worden uitgevoerd op basis van de omgeving. Een implementatietaak en een traditionele taak kunnen zich in dezelfde fase bevinden. Azure DevOps ondersteunt de runOnce-, rolling- en canary-strategieën .

Implementatietaken bieden de volgende voordelen:

  • Implementatiegeschiedenis: u krijgt de implementatiegeschiedenis over pipelines, tot op het niveau van een specifieke resource en status van de implementaties voor controle en audit.
  • Implementatiestrategie toepassen: u definieert hoe uw toepassing wordt geïmplementeerd.

Bij een implementatieopdracht wordt de bronrepository niet automatisch gekloond. U kunt de bronopslagplaats in uw taak uitchecken met checkout: self.

Notitie

Dit artikel is gericht op implementatie met implementatietaken. Raadpleeg Overzicht van implementatie naar Azure om te leren hoe u naar Azure kunt implementeren met behulp van pijplijnen.

Schema

Ga naar het YAML-schema om de jobs.deployment en jobs.deployment.environment definities te zien.

Voor virtuele machines hoeft u geen pool te definiëren. Alle stappen die u in een implementatietaak met een virtuele-machineresource definieert, worden uitgevoerd op die virtuele machine en niet op de agent in de pool. Voor andere resourcetypen, zoals Kubernetes, moet u een pool definiëren, zodat taken op die computer kunnen worden uitgevoerd.

Implementatiestrategieën

Wanneer u toepassingsupdates implementeert, is het belangrijk dat de techniek die u gebruikt om de update te leveren:

  • Initialisatie inschakelen.
  • Implementeer de update.
  • Routeer verkeer naar de bijgewerkte versie.
  • Test de bijgewerkte versie na het routeren van verkeer.
  • In het geval van een fout voert u stappen uit om te herstellen naar de laatst bekende goede versie.

We bereiken dit door levenscyclushooks te gebruiken die stappen kunnen uitvoeren tijdens de implementatie. Elk van de levenscyclus-hooks wordt omgezet in een agenttaak of een servertaak (of een container- of validatietaak in de toekomst), afhankelijk van het pool kenmerk. De levenscyclushooks erven standaard de pool over die is gespecificeerd door de deployment-taak.

Implementatietaken maken gebruik van de $(Pipeline.Workspace) systeemvariabele.

Beschrijvingen van levenscyclushook

preDeploy: Wordt gebruikt om stappen uit te voeren waarmee resources worden geïnitialiseerd voordat de implementatie van de toepassing wordt gestart.

deploy: Wordt gebruikt om stappen uit te voeren waarmee uw toepassing wordt geïmplementeerd. Downloadartefacttaak wordt alleen automatisch geïnjecteerd in de deploy hook voor implementatietaken. Als u wilt stoppen met het downloaden van artefacten, gebruikt - download: none of kiest u specifieke artefacten die u wilt downloaden door de taak Pijplijnartefact downloaden op te geven.

routeTraffic: Wordt gebruikt om stappen uit te voeren die het verkeer naar de bijgewerkte versie afhandelen.

postRouteTraffic: Wordt gebruikt om de stappen uit te voeren nadat het verkeer is omgeleid. Normaal gesproken bewaken deze taken de status van de bijgewerkte versie voor een gedefinieerd interval.

on: failure of on: success: wordt gebruikt om stappen uit te voeren voor terugdraaiacties of opschonen.

Implementatiestrategie voor RunOnce

runOnce is de eenvoudigste implementatiestrategie waarbij alle levenscyclushaken, namelijk preDeploydeploy, routeTrafficen postRouteTraffic, eenmaal worden uitgevoerd. Daarna wordt on:success of on:failure uitgevoerd.

strategy: 
    runOnce:
      preDeploy:        
        pool: [ server | pool ] # See pool schema.        
        steps:
        - script: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
      deploy:          
        pool: [ server | pool ] # See pool schema.        
        steps:
        ...
      routeTraffic:         
        pool: [ server | pool ]         
        steps:
        ...        
      postRouteTraffic:          
        pool: [ server | pool ]        
        steps:
        ...
      on:
        failure:         
          pool: [ server | pool ]           
          steps:
          ...
        success:          
          pool: [ server | pool ]           
          steps:
          ...

Als u zelf-hostende agents gebruikt, kunt u de opties voor het opschonen van de werkruimte gebruiken om uw implementatiewerkruimte op te schonen.

  jobs:
  - deployment: MyDeploy
    pool:
      vmImage: 'ubuntu-latest'
    workspace:
      clean: all
    environment: staging

Doorlopende implementatiestrategie

Een rolling implementatie vervangt exemplaren van de vorige versie van een toepassing door exemplaren van de nieuwe versie van de toepassing op een vaste set virtuele machines (rolling set) in elke iteratie.

Momenteel ondersteunen we alleen de doorlopende strategie voor VM-resources.

Een rolling implementatie wacht bijvoorbeeld meestal op implementaties op elke set virtuele machines te wachten totdat deze zijn voltooid voordat wordt verdergegaan met de volgende sets implementaties. U kunt een statuscontrole uitvoeren na elke iteratie en als er een belangrijk probleem optreedt, kan de rolling implementatie worden gestopt.

Rolling implementaties kunnen worden geconfigureerd door het trefwoord rolling: onder het strategy: knooppunt op te geven. De strategy.name variabele is beschikbaar in dit strategieblok, waarbij de naam van de strategie wordt gebruikt. In dit geval rollend.

strategy:
  rolling:
    maxParallel: [ number or percentage as x% ]
    preDeploy:        
      steps:
      - script: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
    deploy:          
      steps:
      ...
    routeTraffic:         
      steps:
      ...        
    postRouteTraffic:          
      steps:
      ...
    on:
      failure:         
        steps:
        ...
      success:          
        steps:
        ...

Alle levenscyclushooks worden ondersteund en er worden levenscyclushook-jobs gemaakt die op elke virtuele machine worden uitgevoerd.

preDeploy, deploy, routeTrafficen postRouteTraffic worden eenmaal per batchgrootte uitgevoerd die is gedefinieerd door maxParallel. Vervolgens wordt of on: success of on: failure uitgevoerd.

Met maxParallel: <# or % of VMs> kunt u het aantal of percentage virtuele-machinedoelen beheren waarop parallellisering moet worden toegepast tijdens de implementatie. Dit zorgt ervoor dat de app wordt uitgevoerd op deze machines en kan aanvragen verwerken terwijl de implementatie plaatsvindt op de rest van de machines, waardoor de algehele downtime wordt verminderd.

Notitie

Er zijn enkele bekende hiaten in deze functie. Wanneer u bijvoorbeeld een fase opnieuw probeert, wordt de implementatie opnieuw uitgevoerd op alle VM's, niet alleen mislukte doelen.

Canary-implementatiestrategie

De Canary-implementatiestrategie is een geavanceerde implementatiestrategie waarmee het risico wordt beperkt dat gepaard gaat met het implementeren van nieuwe versies van toepassingen. Met deze strategie kunt u de wijzigingen eerst implementeren in een kleine subset van servers. Naarmate u meer vertrouwen krijgt in de nieuwe versie, kunt u deze vrijgeven aan meer servers in uw infrastructuur en meer verkeer naar de versie routeren.

strategy: 
    canary:
      increments: [ number ]
      preDeploy:        
        pool: [ server | pool ] # See pool schema.        
        steps:
        - script: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
      deploy:          
        pool: [ server | pool ] # See pool schema.        
        steps:
        ...
      routeTraffic:         
        pool: [ server | pool ]         
        steps:
        ...        
      postRouteTraffic:          
        pool: [ server | pool ]        
        steps:
        ...
      on:
        failure:         
          pool: [ server | pool ]           
          steps:
          ...
        success:          
          pool: [ server | pool ]           
          steps:
          ...

Canary-implementatiestrategie ondersteunt de preDeploy levenscyclushook (eenmaal uitgevoerd) en herhaalt met de deploy, routeTrafficen postRouteTraffic levenscyclushaken. Vervolgens eindigt het met de success of failure haak.

De volgende variabelen zijn beschikbaar in deze strategie:

strategy.name: Naam van de strategie. Bijvoorbeeld kanarie.
strategy.action: De actie die moet worden uitgevoerd op het Kubernetes-cluster. Bijvoorbeeld implementeren, promoveren of weigeren.
strategy.increment: De incrementele waarde die wordt gebruikt in de huidige interactie. Deze variabele is alleen beschikbaar in deploy, routeTraffic en postRouteTraffic levenscyclushooks.

Voorbeelden

Implementatiestrategie voor RunOnce

In het volgende voorbeeld toont het YAML-fragment een eenvoudig gebruik van een implementatietaak met behulp van de runOnce implementatiestrategie. Het voorbeeld bevat een betaalstap.


jobs:
  # Track deployments on the environment.
- deployment: DeployWeb
  displayName: deploy Web App
  pool:
    vmImage: 'ubuntu-latest'
  # Creates an environment if it doesn't exist.
  environment: 'smarthotel-dev'
  strategy:
    # Default deployment strategy, more coming...
    runOnce:
      deploy:
        steps:
        - checkout: self 
        - script: echo my first deployment

Bij elke uitvoering van deze taak wordt de implementatiegeschiedenis vastgelegd op basis van de smarthotel-dev omgeving.

Notitie

  • Het is ook mogelijk om een omgeving met lege resources te maken en deze te gebruiken als een abstracte shell om de implementatiegeschiedenis vast te leggen, zoals wordt weergegeven in het vorige voorbeeld.

In het volgende voorbeeld ziet u hoe een pijplijn kan verwijzen naar zowel een omgeving als een resource die moet worden gebruikt als het doel voor een implementatietaak.

jobs:
- deployment: DeployWeb
  displayName: deploy Web App
  pool:
    vmImage: 'ubuntu-latest'
  # Records deployment against bookings resource - Kubernetes namespace.
  environment: 'smarthotel-dev.bookings'
  strategy: 
    runOnce:
      deploy:
        steps:
          # No need to explicitly pass the connection details.
        - task: KubernetesManifest@0
          displayName: Deploy to Kubernetes cluster
          inputs:
            action: deploy
            namespace: $(k8sNamespace)
            manifests: |
              $(System.ArtifactsDirectory)/manifests/*
            imagePullSecrets: |
              $(imagePullSecret)
            containers: |
              $(containerRegistry)/$(imageRepository):$(tag)

Deze benadering heeft de volgende voordelen:

  • Registreert de implementatiegeschiedenis van een specifieke resource binnen de omgeving, in plaats van de geschiedenis op alle resources in de omgeving op te nemen.
  • Stappen in de implementatietaak nemen automatisch de verbindingsgegevens van de resource over (in dit geval een Kubernetes-naamruimte), smarthotel-dev.bookingsomdat de implementatietaak is gekoppeld aan de omgeving. Dit is handig in de gevallen waarin dezelfde verbindingsgegevens zijn ingesteld voor meerdere stappen van de taak.

Notitie

Als u een privé-AKS-cluster gebruikt, moet u ervoor zorgen dat u bent verbonden met het virtuele netwerk van het cluster, omdat het EINDPUNT van de API-server niet beschikbaar is via een openbaar IP-adres.

Azure Pipelines raadt u aan een zelf-hostende agent in te stellen binnen een VNET dat toegang heeft tot het virtuele netwerk van het cluster. Zie Opties voor het maken van verbinding met het privécluster voor meer informatie.

Doorlopende implementatiestrategie

De rolling-strategie voor VM's werkt in elke iteratie maximaal vijf doelen bij. maxParallel bepaalt het aantal doelen dat parallel kan worden geïmplementeerd. Bij de selectie wordt rekening gehouden met een absoluut aantal of percentage doelen dat op elk gewenst moment beschikbaar moet blijven, met uitzondering van de doelen waarop wordt geïmplementeerd. Het wordt ook gebruikt om de voorwaarden voor succes en fouten tijdens de implementatie te bepalen.

jobs: 
- deployment: VMDeploy
  displayName: web
  environment:
    name: smarthotel-dev
    resourceType: VirtualMachine
  strategy:
    rolling:
      maxParallel: 5  #for percentages, mention as x%
      preDeploy:
        steps:
        - download: current
          artifact: drop
        - script: echo initialize, cleanup, backup, install certs
      deploy:
        steps:
        - task: IISWebAppDeploymentOnMachineGroup@0
          displayName: 'Deploy application to Website'
          inputs:
            WebSiteName: 'Default Web Site'
            Package: '$(Pipeline.Workspace)/drop/**/*.zip'
      routeTraffic:
        steps:
        - script: echo routing traffic
      postRouteTraffic:
        steps:
        - script: echo health check post-route traffic
      on:
        failure:
          steps:
          - script: echo Restore from backup! This is on failure
        success:
          steps:
          - script: echo Notify! This is on success

Canary-implementatiestrategie

In het volgende voorbeeld implementeert de canary-strategie voor AKS eerst de wijzigingen met 10 procent van de pods, gevolgd door 20 procent, terwijl de gezondheid in de gaten wordt gehouden tijdens postRouteTraffic. Als alles goed gaat, zal het promoveren tot 100 procent.

jobs: 
- deployment: 
  environment: smarthotel-dev.bookings
  pool: 
    name: smarthotel-devPool
  strategy:                  
    canary:      
      increments: [10,20]  
      preDeploy:                                     
        steps:           
        - script: initialize, cleanup....   
      deploy:             
        steps: 
        - script: echo deploy updates... 
        - task: KubernetesManifest@0 
          inputs: 
            action: $(strategy.action)       
            namespace: 'default' 
            strategy: $(strategy.name) 
            percentage: $(strategy.increment) 
            manifests: 'manifest.yml' 
      postRouteTraffic: 
        pool: server 
        steps:           
        - script: echo monitor application health...   
      on: 
        failure: 
          steps: 
          - script: echo clean-up, rollback...   
        success: 
          steps: 
          - script: echo checks passed, notify... 

Gebruik pijplijndecorators om stappen automatisch te injecteren

Pipeline-decorators kunnen worden gebruikt in implementatietaken om elke aangepaste stap (bijvoorbeeld kwetsbaarheidsscanner) automatisch te injecteren in elke uitvoering van een levenscyclus-hook van elke implementatietaak. Omdat pijplijn-decorators kunnen worden toegepast op alle pijplijnen in een organisatie, kan dit worden toegepast als onderdeel van het afdwingen van veilige implementatieprocedures.

Daarnaast kunnen implementatietaken worden uitgevoerd als een containertaak , samen met services side-car , indien gedefinieerd.

Ondersteuning voor uitvoervariabelen

Definieer uitvoervariabelen in de levenscyclushook van een implementatietaak en verbruik deze in andere downstreamstappen en taken binnen dezelfde fase.

Als u variabelen tussen fasen wilt delen, voert u een artefact in één fase uit en gebruikt u het in een volgende fase of gebruikt u de stageDependencies syntaxis die in variabelen wordt beschreven.

Tijdens het uitvoeren van implementatiestrategieën hebt u toegang tot uitvoervariabelen tussen taken met behulp van de volgende syntaxis.

  • Voor runOnce-strategie : $[dependencies.<job-name>.outputs['<job-name>.<step-name>.<variable-name>']] (bijvoorbeeld $[dependencies.JobA.outputs['JobA.StepA.VariableA']])
  • Voor runOnce-strategie en een resourcetype: $[dependencies.<job-name>.outputs['Deploy_<resource-name>.<step-name>.<variable-name>']]. (bijvoorbeeld, $[dependencies.JobA.outputs['Deploy_VM1.StepA.VariableA']])
  • Voor kanariestrategie : $[dependencies.<job-name>.outputs['<lifecycle-hookname>_<increment-value>.<step-name>.<variable-name>']]
  • Voor lopende strategie: $[dependencies.<job-name>.outputs['<lifecycle-hookname>_<resource-name>.<step-name>.<variable-name>']]
# Set an output variable in a lifecycle hook of a deployment job executing canary strategy.
- deployment: A
  pool:
    vmImage: 'ubuntu-latest'
  environment: staging
  strategy:                  
    canary:      
      increments: [10,20]  # Creates multiple jobs, one for each increment. Output variable can be referenced with this.
      deploy:
        steps:
        - bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
          name: setvarStep
        - bash: echo $(setvarStep.myOutputVar)
          name: echovar

# Map the variable from the job.
- job: B
  dependsOn: A
  pool:
    vmImage: 'ubuntu-latest'
  variables:
    myVarFromDeploymentJob: $[ dependencies.A.outputs['deploy_10.setvarStep.myOutputVar'] ]
  steps:
  - script: "echo $(myVarFromDeploymentJob)"
    name: echovar

Geef voor een runOnce taak de naam van de taak op in plaats van de levenscyclushook:

# Set an output variable in a lifecycle hook of a deployment job executing runOnce strategy.
- deployment: A
  pool:
    vmImage: 'ubuntu-latest'
  environment: staging
  strategy:                  
    runOnce:
      deploy:
        steps:
        - bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
          name: setvarStep
        - bash: echo $(setvarStep.myOutputVar)
          name: echovar

# Map the variable from the job.
- job: B
  dependsOn: A
  pool:
    vmImage: 'ubuntu-latest'
  variables:
    myVarFromDeploymentJob: $[ dependencies.A.outputs['A.setvarStep.myOutputVar'] ]
  steps:
  - script: "echo $(myVarFromDeploymentJob)"
    name: echovar

Wanneer u een omgeving in een implementatietaak definieert, varieert de syntaxis van de uitvoervariabele, afhankelijk van hoe de omgeving wordt gedefinieerd. In dit voorbeeld env1 wordt de korte notatie gebruikt en env2 bevat de volledige syntaxis met een gedefinieerd resourcetype.

stages:
- stage: StageA
  jobs:
  - deployment: A1
    pool:
      vmImage: 'ubuntu-latest'
    environment: env1
    strategy:                  
      runOnce:
        deploy:
          steps:
          - bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
            name: setvarStep
          - bash: echo $(System.JobName)
  - deployment: A2
    pool:
      vmImage: 'ubuntu-latest'
    environment: 
      name: env2
      resourceName: vmsfortesting
      resourceType: virtualmachine
    strategy:                  
      runOnce:
        deploy:
          steps:
          - script: echo "##vso[task.setvariable variable=myOutputVarTwo;isOutput=true]this is the second deployment variable value"
            name: setvarStepTwo
  
  - job: B1
    dependsOn: A1
    pool:
      vmImage: 'ubuntu-latest'
    variables:
      myVarFromDeploymentJob: $[ dependencies.A1.outputs['A1.setvarStep.myOutputVar'] ]
      
    steps:
    - script: "echo $(myVarFromDeploymentJob)"
      name: echovar
 
  - job: B2
    dependsOn: A2
    pool:
      vmImage: 'ubuntu-latest'
    variables:
      myVarFromDeploymentJob: $[ dependencies.A2.outputs['A2.setvarStepTwo.myOutputVarTwo'] ]
      myOutputVarTwo: $[ dependencies.A2.outputs['Deploy_vmsfortesting.setvarStepTwo.myOutputVarTwo'] ]
    
    steps:
    - script: "echo $(myOutputVarTwo)"
      name: echovartwo

Wanneer u een variabele uitvoert vanuit een taak in fase één, en u wilt deze refereren in een implementatietaak in de volgende fase, moet u verschillende syntaxis gebruiken, afhankelijk van of u de variabele wilt instellen of deze wilt gebruiken als voorwaarde voor de fase.

stages:
- stage: StageA
  jobs:
  - job: A1
    steps:
      - pwsh: echo "##vso[task.setvariable variable=RunStageB;isOutput=true]true"
        name: setvarStep
      - bash: echo $(System.JobName)

- stage: StageB
  dependsOn: 
    - StageA
 
  # when referring to another stage, stage name is included in variable path
  condition: eq(dependencies.StageA.outputs['A1.setvarStep.RunStageB'], 'true')
  
  # Variables reference syntax differs slightly from inter-stage condition syntax
  variables:
    myOutputVar: $[stageDependencies.StageA.A1.outputs['setvarStep.RunStageB']]
  jobs:
  - deployment: B1
    pool:
      vmImage: 'ubuntu-latest'
    environment: envB
    strategy:                  
      runOnce:
        deploy:
          steps:
          - bash: echo $(myOutputVar)

Wanneer u een variabele uitvoert vanuit een implementatietaak, gebruikt u de syntaxis van stageDependencies om ernaar te verwijzen vanuit de volgende fase (bijvoorbeeld $[stageDependencies.<stage-name>.<job-name>.outputs[Deploy_<resource-name>.<step-name>.<variable-name>]]).

stages:
- stage: StageA
  jobs:
    - deployment: A1
      environment: 
        name:  env1
        resourceName: DevEnvironmentV
        resourceType: virtualMachine
      strategy:
        runOnce:
          deploy:
            steps:
              - script: echo "##vso[task.setvariable variable=myVar;isOutput=true]true"
                name: setvarStep
              - script: |
                  echo "Value of myVar in the same Job : $(setVarStep.myVar)"
                displayName: 'Verify variable in StageA'
- stage: StageB
  dependsOn: StageA

  # Full Variables syntax for inter-stage jobs
  variables:
    myOutputVar: $[stageDependencies.StageA.A1.outputs['Deploy_DevEnvironmentV.setvarStep.myVar']]
  jobs:
  - deployment: B1
    pool:
      vmImage: 'ubuntu-latest'
    environment: envB
    strategy:                  
      runOnce:
        deploy:
          steps:
          - bash: echo $(myOutputVar)

Meer informatie over het instellen van een uitvoervariabele voor meerdere taken

Veelgestelde vragen

Mijn pijplijn zit vast met de melding 'Taak is in behandeling...'. Hoe kan ik dit oplossen?

Dit kan gebeuren wanneer er een naamconflict is tussen twee taken. Controleer of alle implementatietaken in dezelfde fase een unieke naam hebben en dat de taak- en fasenamen geen trefwoorden bevatten. Als het probleem niet wordt opgelost door de naam te wijzigen, raadpleegt u de probleemoplossing voor pijplijnuitvoeringen.

Worden decorators ondersteund in implementatiegroepen?

Nee U kunt geen decorators gebruiken in implementatiegroepen.