Bereitstellungsaufträge

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

Wichtig

  • Auftrags- und Phasennamen dürfen keine Schlüsselwörter enthalten (Beispiel: deployment).
  • Jeder Auftrag in einer Phase muss einen eindeutigen Namen haben.

Für YAML-Pipelines empfehlen wir Ihnen, Ihre Bereitstellungsschritte in einem speziellen Auftrag anzuordnen, der als Bereitstellungsauftrag bezeichnet wird. Ein Bereitstellungsauftrag ist eine Sammlung von Schritten, die nacheinander für die Umgebung ausgeführt werden. Ein Bereitstellungsauftrag und ein herkömmlicher Auftrag können in der gleichen Phase vorhanden sein. Azure DevOps unterstützt die Strategien runOnce, rolling und canary .

Bereitstellungsaufträge haben folgende Vorteile:

  • Bereitstellungsverlauf: Sie erhalten einen pipelineübergreifenden Bereitstellungsverlauf bis hin zu einer bestimmten Ressource und zum Status der Bereitstellungen für die Überwachung.
  • Anwenden einer Bereitstellungsstrategie: Sie definieren, wie das Rollout Ihrer Anwendung ablaufen soll.

Ein Bereitstellungsauftrag klont nicht automatisch das Quellrepository. Sie können das Quellrepository in Ihrem Auftrag mit checkout: self auschecken.

Hinweis

Dieser Artikel konzentriert sich auf die Bereitstellung mithilfe von Bereitstellungsaufträgen. Informationen zum Bereitstellen in Azure mit Pipelines finden Sie unter Bereitstellen in Azure: Übersicht.

Schema

Hier sehen Sie die vollständige Syntax für die Angabe eines Bereitstellungsauftrags:

jobs:
- deployment: string   # name of the deployment job, A-Z, a-z, 0-9, and underscore. The word "deploy" is a keyword and is unsupported as the deployment name.
  displayName: string  # friendly name to display in the UI
  pool:                # not required for virtual machine resources
    name: string       # Use only global level variables for defining a pool name. Stage/job level variables are not supported to define pool name.
    demands: string | [ string ]
  workspace:
    clean: outputs | resources | all # what to clean up before the job runs
  dependsOn: string
  condition: string
  continueOnError: boolean                # 'true' if future jobs should run even if this job fails; defaults to 'false'
  container: containerReference # container to run this job inside
  services: { string: string | container } # container resources to run as a service container
  timeoutInMinutes: nonEmptyString        # how long to run the job before automatically cancelling
  cancelTimeoutInMinutes: nonEmptyString  # how much time to give 'run always even if cancelled tasks' before killing them
  variables: # several syntaxes, see specific section
  environment: string  # target environment name and optionally a resource name to record the deployment history; format: <environment-name>.<resource-name>
  strategy:
    runOnce:    #rolling, canary are the other strategies that are supported
      deploy:
        steps: [ script | bash | pwsh | powershell | checkout | task | templateReference ]

Es gibt eine detailliertere, alternative Syntax, die Sie auch für die environment-Eigenschaft verwenden können.

environment:
    name: string # Name of environment.
    resourceName: string # Name of resource.
    resourceId: string # Id of resource.
    resourceType: string # Type of environment resource.
    tags: string # List of tag filters.

Für virtuelle Computer müssen Sie keinen Pool definieren. Alle Schritte, die Sie in einem Bereitstellungsauftrag mit einer VM-Ressource definieren, werden für diesen virtuellen Computer und nicht für den Agent im Pool ausgeführt. Für andere Ressourcentypen wie Kubernetes müssen Sie einen Pool definieren, damit Aufgaben auf diesem Computer ausgeführt werden können.

Bereitstellungsmethoden

Wenn Sie Anwendungsupdates bereitstellen, ist es wichtig, dass folgende Technik zum Bereitstellen des Updates verwendet wird:

  • Aktivieren der Initialisierung.
  • Bereitstellen des Updates.
  • Weiterleiten des Datenverkehrs an die aktualisierte Version.
  • Testen der aktualisierten Version nach dem Weiterleiten des Datenverkehrs.
  • Wenn ein Fehler auftritt, führen Sie Schritte zum Wiederherstellen der letzten bekannten fehlerfreien Version aus.

Dies wird mithilfe von Lebenszyklushooks erreicht, die Schritte während der Bereitstellung ausführen können. Jeder der Lebenszyklushooks wird je nach pool-Attribut in einen Agent- oder Serverauftrag (oder einen Container- oder Validierungsauftrag in der Zukunft) aufgelöst. Standardmäßig erben die Lebenszyklushooks den vom deployment-Auftrag angegebenen pool.

Bereitstellungsaufträge verwenden die Systemvariable $(Pipeline.Workspace).

Beschreibungen von Lebenszyklushooks

preDeploy: Zum Ausführen von Schritten, mit denen vor dem Start der Anwendungsbereitstellung Ressourcen initialisiert werden.

deploy: Zum Ausführen von Schritten, mit denen Ihre Anwendung bereitgestellt wird. Die Aufgabe „download artifact“ wird nur in den deploy-Hook für Bereitstellungsaufträge automatisch eingefügt. Um das Herunterladen von Artefakten zu beenden, verwenden Sie - download: none. Alternativ können Sie bestimmte Artefakte auswählen, die heruntergeladen werden sollen, indem Sie die Aufgabe „Pipelineartefakt herunterladen“ definieren.

routeTraffic: Zum Ausführen von Schritten, die dem Datenverkehr zur aktualisierten Version dienen.

postRouteTraffic: Zum Ausführen von Schritten nach dem Weiterleiten des Datenverkehrs. In der Regel überwachen diese Aufgaben die Integrität der aktualisierten Version für ein definiertes Intervall.

on: failure oder on: success: Zum Ausführen von Schritten für Rollback-Aktionen oder zum Bereinigen.

RunOnce-Bereitstellungsstrategie

runOnce: ist die einfachste Bereitstellungsstrategie, bei der alle Lebenszyklushooks, also preDeploydeploy, routeTraffic und postRouteTraffic, einmal ausgeführt werden. Danach wird entweder on:success oder on:failure ausgeführt.

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:
          ...

Wenn Sie selbstgehostete Agents verwenden, können Sie Optionen zum Bereinigen des Arbeitsbereichs verwenden, um Ihren Bereitstellungsarbeitsbereich zu bereinigen.

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

Die Rolling-Bereitstellungsmethode

Bei einer parallelen Bereitstellung werden bei jeder Iteration auf einer festgelegten Gruppe von virtuellen Computern (Gruppe für parallele Vorgänge) Instanzen der vorherigen Version einer Anwendung durch Instanzen der neuen Version ersetzt.

Derzeit wird nur die rollierende Strategie für VM-Ressourcen unterstützt.

Eine rollierende Bereitstellung wartet beispielsweise in der Regel, bis die Bereitstellungen auf den einzelnen virtuellen Computern abgeschlossen sind, bevor mit der nächsten Gruppe von Bereitstellungen fortgefahren wird. Sie könnten nach jeder Iteration eine Integritätsprüfung durchführen. Wenn ein schwerwiegendes Problem auftritt, kann die rollierende Bereitstellung angehalten werden.

Für die Konfiguration von rollierenden Bereitstellungen wird unter dem strategy:-Knoten das Schlüsselwort rolling: angegeben. Die strategy.name-Variable ist in diesem Strategieblock verfügbar, sie nimmt den Namen der Strategie an. In diesem Fall „rolling“.

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 Lebenszyklushooks werden unterstützt und Lebenszyklushook-Aufträge werden für die Ausführung auf jedem virtuellen Computer erstellt.

preDeploy, deploy, routeTrafficund postRouteTraffic werden einmal pro durch maxParallel definierter Batchgröße ausgeführt. Danach wird entweder on: success oder on: failure ausgeführt.

Mit maxParallel: <# or % of VMs> können Sie die Anzahl/den Prozentsatz von VM-Zielen steuern, für die parallel bereitgestellt werden soll. Dadurch wird sichergestellt, dass die App auf diesen Computern ausgeführt wird und Anforderungen verarbeiten kann, während die Bereitstellung auf den restlichen Computern erfolgt, wodurch Ausfallzeiten insgesamt reduziert werden.

Hinweis

Es gibt einige bekannte Lücken in diesem Feature. Wenn Sie z. B. eine Phase wiederholen, wird die Bereitstellung auf allen VMs erneut ausgeführt, nicht nur auf Zielen mit Fehlern.

Die Canary-Bereitstellungsmethode

Die Canary-Bereitstellungsstrategie ist eine erweiterte Bereitstellungsstrategie, die hilft, das Risiko bei der Einführung neuer Anwendungsversionen zu minimieren. Mithilfe dieser Strategie können Sie zuerst die Änderungen bei einer kleinen Teilmenge von Servern ausführen. Wenn das Vertrauen in die neue Version zunimmt, können Sie sie für weitere Server in Ihrer Infrastruktur freigeben und mehr Datenverkehr an diese weiterleiten.

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:
          ...

Die Canary-Bereitstellungsstrategie unterstützt den preDeploy-Lebenszyklushook (einmal ausgeführt) und durchläuft die deploy-, routeTraffic-und postRouteTraffic-Lebenszyklushooks. Anschließend wird über den success- oder failure-Hook beendet.

Die folgenden Variablen sind in dieser Strategie verfügbar:

strategy.name: Name der Strategie. Beispiel: „Canary“.
strategy.action: Die Aktion, die für den Kubernetes-Cluster ausgeführt werden soll. Beispiel: Bereitstellen, höher stufen oder Ablehnen.
strategy.increment: Der in der aktuellen Interaktion verwendete Inkrementwert. Diese Variable ist nur in deploy-, routeTraffic- und postRouteTraffic-Lebenszyklus-Hooks verfügbar.

Beispiele

RunOnce-Bereitstellungsstrategie

Der folgende YAML-Beispielausschnitt zeigt eine einfache Verwendung eines Bereitstellungsauftrags mithilfe der runOnce-Bereitstellungsstrategie. Das Beispiel umfasst einen Checkout-Schritt.


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

Bei jeder Ausführung dieses Auftrags wird ein Bereitstellungsverlauf für die smarthotel-dev-Umgebung erfasst.

Hinweis

  • Es ist auch möglich, eine Umgebung mit leeren Ressourcen zu erstellen und diese als abstrakte Shell zum Aufzeichnen des Bereitstellungsverlaufs zu verwenden, wie im vorherigen Beispiel gezeigt.

Im nächsten Beispiel wird veranschaulicht, wie eine Pipeline sowohl auf eine Umgebung als auch auf eine Ressource verweisen kann, die als Ziel für einen Bereitstellungsauftrag verwendet werden soll.

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)

Dieser Ansatz hat folgende Vorteile:

  • Zeichnet den Bereitstellungsverlauf für eine bestimmte Ressource in der Umgebung auf, anstatt den Verlauf für alle Ressourcen in der Umgebung aufzuzeichnen.
  • Schritte im Bereitstellungsauftrag erben automatisch die Verbindungsdetails der Ressource (in diesem Fall ein Kubernetes-Namespace, smarthotel-dev.bookings) da der Bereitstellungsauftrag mit der Umgebung verknüpft ist. Dies ist nützlich, wenn dieselben Verbindungsdetails für mehrere Schritte des Auftrags festgelegt sind.

Die Rolling-Bereitstellungsmethode

Die rollierende Strategie für VMs aktualisiert bei jeder Iteration bis zu fünf Ziele. maxParallel bestimmt die Anzahl von Zielen, auf denen eine parallele Bereitstellung erfolgen kann. Die Auswahl berücksichtigt die absolute Anzahl oder einen Prozentsatz der Ziele, die zu jedem Zeitpunkt verfügbar bleiben müssen, ausgenommen die Ziele, auf denen die Bereitstellung erfolgt. Hiermit werden auch die Erfolgs- und Fehlerbedingungen während der Bereitstellung bestimmt.

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

Die Canary-Bereitstellungsmethode

Im nächsten Beispiel stellt die Canary-Strategie für AKS die Änderungen zuerst mit 10-Prozent-Pods bereit, gefolgt von 20 Prozent, wobei die Integrität während postRouteTraffic überwacht wird. Wenn alles gut geht, wird auf 100 Prozent heraufgestuft.

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

Verwenden von Pipelinedecorators zum automatischen Einfügen von Schritten

Pipelinedecorators können in Bereitstellungsaufträgen verwendet werden, um jeden benutzerdefinierten Schritt (z. B. die Sicherheitsrisikoüberprüfung) automatisch in jede Lebenszyklushook-Ausführung jedes Bereitstellungsauftrags einzuschleusen. Da Pipelinedecorators auf alle Pipelines in einer Organisation angewendet werden können, kann dies für die Erzwingung sicherer Bereitstellungsmethoden angewendet werden.

Darüber hinaus können Bereitstellungsaufträge als Containerauftrag zusammen mit Service-Sidecar ausgeführt werden, wenn definiert.

Unterstützung für Ausgabevariablen

Definieren Sie Ausgabevariablen in den Lebenszyklushooks eines Bereitstellungsauftrags und verwenden Sie sie in anderen nachgeschalteten Schritten und Aufträgen derselben Phase.

Um Variablen zwischen Phasen weiterzugeben, geben Sie ein Artefakt in einer Phase aus und verwenden Sie es dann in einer nachfolgenden Phase, oder verwenden Sie die unter Variablen beschriebene stageDependencies-Syntax.

Beim Ausführen von Bereitstellungsstrategien können Sie mit der folgenden Syntax auftragsübergreifend auf Ausgabevariablen zugreifen.

  • Für die runOnce-Strategie: $[dependencies.<job-name>.outputs['<job-name>.<step-name>.<variable-name>']] (z. B. $[dependencies.JobA.outputs['JobA.StepA.VariableA']])
  • Für runOnce-Strategie und einen resourceType: $[dependencies.<job-name>.outputs['<job-name>_<resource-name>.<step-name>.<variable-name>']]. (Beispiel: $[dependencies.JobA.outputs['Deploy_VM1.StepA.VariableA']])
  • Für die Canary-Strategie : $[dependencies.<job-name>.outputs['<lifecycle-hookname>_<increment-value>.<step-name>.<variable-name>']]
  • Für die rollierende 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

Geben Sie für einen runOnce-Auftrag den Namen des Auftrags anstelle des Lebenszyklushooks an:

# 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

Wenn Sie eine Umgebung in einem Bereitstellungsauftrag definieren, hängt die Syntax der Ausgabevariablen davon ab, wie die Umgebung definiert wird. In diesem Beispiel verwendet env1 die Kurzschreibweise und env2 enthält die vollständige Syntax mit einem definierten Ressourcentyp.

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
      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.myOutputVar'] ]
      myOutputVarTwo: $[ dependencies.A2.outputs['Deploy_vmsfortesting.setvarStepTwo.myOutputVarTwo'] ]
    
    steps:
    - script: "echo $(myOutputVarTwo)"
      name: echovartwo

Wenn Sie eine Variable aus einem Bereitstellungsauftrag ausgeben, wird bei Verweisen im nächsten Auftrag eine andere Syntax verwendet, je nachdem, ob Sie eine Variable festlegen oder sie als eine Bedingung für die Phase verwenden möchten.

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)

Weitere Informationen zum Festlegen einer Ausgabevariable für mehrere Aufträge

Häufig gestellte Fragen

Meine Pipeline bleibt mit der Meldung „Auftrag steht aus...“ hängen. Wie kann ich dieses Problem beheben?

Dies kann vorkommen, wenn es einen Namenskonflikt zwischen zwei Aufträgen gibt. Vergewissern Sie sich, dass alle Bereitstellungsaufträge in derselben Phase einen eindeutigen Namen haben und dass Auftrags- und Phasennamen keine Schlüsselwörter enthalten. Wenn das Problem durch die Umbenennung nicht behoben wird, ziehen Sie die Problembehandlung für Pipelineausführungen zurate.

Werden Decorators in Bereitstellungsgruppen unterstützt?

Nein. Sie können keine Decorators in Bereitstellungsgruppen verwenden.