Úlohy nasazení

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

Důležité

  • Názvy úloh a fází nesmí obsahovat klíčová slova (například: deployment).
  • Každá úloha ve fázi musí mít jedinečný název.

V kanálech YAML doporučujeme umístit kroky nasazení do speciálního typu úlohy označované jako úloha nasazení. Úloha nasazení je kolekce kroků, které se v rámci prostředí spouštějí postupně. Úloha nasazení a tradiční úloha mohou existovat ve stejné fázi. Azure DevOps podporuje runOnce, rolling a kanárské strategie.

Úlohy nasazení poskytují následující výhody:

  • Historie nasazení: Získáte historii nasazení napříč kanály, až po konkrétní prostředky a stav nasazení pro účely auditování.
  • Využití strategie nasazení: Definujete, jak se vaše aplikace zavádí.

Úloha nasazení automaticky nenaklonuje zdrojové úložiště. Zdrojové úložiště můžete rezervovat v rámci své úlohy pomocí checkout: selfnástroje .

Poznámka:

Tento článek se zaměřuje na nasazení s úlohami nasazení. Informace o nasazení do Azure pomocí kanálů najdete v přehledu nasazení do Azure.

Schéma

Tady je úplná syntaxe pro zadání úlohy nasazení:

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 ]

K dispozici je podrobnější, alternativní syntaxe, kterou můžete použít také pro environment vlastnost.

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.

U virtuálních počítačů nemusíte definovat fond. Všechny kroky, které definujete v úloze nasazení s prostředkem virtuálního počítače, se budou spouštět s tímto virtuálním počítačem, a ne s agentem ve fondu. U jiných typů prostředků, jako je Kubernetes, je potřeba definovat fond, aby se na tomto počítači mohly spouštět úlohy.

Strategie nasazení

Při nasazování aktualizací aplikací je důležité, aby technika, kterou používáte k doručení aktualizace,:

  • Povolte inicializaci.
  • Nasaďte aktualizaci.
  • Směrujte provoz na aktualizovanou verzi.
  • Po směrování provozu otestujte aktualizovanou verzi.
  • V případě selhání spusťte kroky pro obnovení na poslední známou dobrou verzi.

Toho dosáhneme pomocí háků životního cyklu, které můžou spouštět kroky během nasazování. Každý z háků životního cyklu se v závislosti na atributu přeloží do úlohy agenta nebo úlohy serveru (nebo kontejneru nebo ověřovací úlohy v budoucnu pool ). Ve výchozím nastavení zdědí pool háky životního cyklu zadané úlohou deployment .

Úlohy nasazení používají systémovou proměnnou $(Pipeline.Workspace) .

Popisy háků životního cyklu

preDeploy: Slouží ke spuštění kroků, které inicializují prostředky před spuštěním nasazení aplikace.

deploy: Slouží ke spuštění kroků, které nasazují vaši aplikaci. Úloha stažení artefaktu se automaticky vloží jenom do deploy háku pro úlohy nasazení. Pokud chcete zastavit stahování artefaktů, použijte - download: none nebo zvolte konkrétní artefakty ke stažení zadáním úlohy Stažení kanálu artefaktu.

routeTraffic: Slouží ke spuštění kroků, které obsluhují provoz do aktualizované verze.

postRouteTraffic: Slouží ke spuštění kroků po směrování provozu. Tyto úlohy obvykle monitorují stav aktualizované verze pro definovaný interval.

on: failure nebo on: success: Slouží ke spuštění kroků pro akce vrácení zpět nebo vyčištění.

Strategie nasazení RunOnce

runOnce je nejjednodušší strategie nasazení, kde se spustí všechny háčky životního cyklu, konkrétně preDeploy deploy, routeTraffica postRouteTraffic, jednou. Pak se on: success buď provede, nebo on: failure se spustí.

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

Pokud používáte agenty v místním prostředí, můžete pracovní prostor vyčistit pomocí možností vyčištění pracovního prostoru.

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

Strategie postupného nasazení

Postupné nasazení nahrazuje instance předchozí verze aplikace instancemi nové verze aplikace na pevné sadě virtuálních počítačů (rolling set) v každé iteraci.

V současné době podporujeme pouze strategii zajištění provozu pro prostředky virtuálních počítačů.

Například postupné nasazení obvykle čeká na dokončení nasazení na každé sadě virtuálních počítačů, než přejdete k další sadě nasazení. Po každé iteraci můžete provést kontrolu stavu a pokud dojde k významnému problému, je možné postupné nasazení zastavit.

Postupné nasazení je možné nakonfigurovat zadáním klíčového strategy: slova rolling: pod uzlem. Proměnná strategy.name je k dispozici v tomto bloku strategie, která přebírá název strategie. V tomto případě se točí.

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

Všechny háky životního cyklu jsou podporované a úlohy háku životního cyklu se vytvoří pro spuštění na každém virtuálním počítači.

preDeploy, , deployrouteTraffica postRouteTraffic jsou prováděny jednou na velikost dávky definované .maxParallel Pak se on: success buď provede, nebo on: failure se spustí.

Pomocí maxParallel: <# or % of VMs>funkce můžete řídit počet/procent cílů virtuálních počítačů, které se mají nasadit paralelně. Tím se zajistí, že aplikace běží na těchto počítačích a dokáže zpracovávat požadavky, zatímco se nasazení provádí na zbývajících počítačích, což snižuje celkový výpadek.

Poznámka:

Tato funkce obsahuje několik známých mezer. Když například zopakujete fázi, znovu spustí nasazení na všech virtuálních počítačích, nejen na neúspěšnýchcílech

Strategie testovacího nasazení

Kanárná strategie nasazení je pokročilá strategie nasazení, která pomáhá zmírnit riziko spojené s zaváděním nových verzí aplikací. Pomocí této strategie můžete nejprve zavést změny malé podmnožině serverů. Jakmile budete mít větší jistotu v nové verzi, můžete ji uvolnit na více serverů ve vaší infrastruktuře a směrovat do ní větší provoz.

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 deployment strategy supports the preDeploy lifecycle hook (executed once) and iterates with the deploy, routeTrafficand postRouteTraffic lifecycle hooks. Pak se ukončí pomocí háku nebo failure hákusuccess.

V této strategii jsou k dispozici následující proměnné:

strategy.name: Název strategie. Například kanár.
strategy.action: Akce, která se má provést v clusteru Kubernetes. Můžete například nasadit, zvýšit úroveň nebo odmítnout.
strategy.increment: Hodnota přírůstku použitá v aktuální interakci. Tato proměnná je k dispozici pouze v deployhácích a routeTrafficpostRouteTraffic v hácích životního cyklu.

Příklady

Strategie nasazení RunOnce

Následující příklad fragment kódu YAML předvádí jednoduché použití úlohy nasazení pomocí runOnce strategie nasazení. Příklad obsahuje krok rezervace.


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

Při každém spuštění této úlohy se historie nasazení zaznamená do smarthotel-dev prostředí.

Poznámka:

  • Je také možné vytvořit prostředí s prázdnými prostředky a použít ho jako abstraktní prostředí k zaznamenání historie nasazení, jak je znázorněno v předchozím příkladu.

Další příklad ukazuje, jak kanál může odkazovat na prostředí i prostředek, které se mají použít jako cíl pro úlohu nasazení.

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)

Tento přístup má následujících výhody:

  • Zaznamenává historii nasazení pro konkrétní prostředek v rámci prostředí, a ne zaznamenává historii všech prostředků v rámci prostředí.
  • Kroky v úloze nasazení automaticky dědí podrobnosti o připojení prostředku (v tomto případě obor názvů smarthotel-dev.bookingsKubernetes), protože úloha nasazení je propojená s prostředím. To je užitečné v případech, kdy je stejný detail připojení nastavený pro více kroků úlohy.

Poznámka:

Pokud používáte privátní cluster AKS, ujistěte se, že jste připojení k virtuální síti clusteru, protože koncový bod serveru rozhraní API není přístupný prostřednictvím veřejné IP adresy.

Azure Pipelines doporučuje nastavit agenta v místním prostředí v rámci virtuální sítě, která má přístup k virtuální síti clusteru. Podrobnosti najdete v tématu Možnosti připojení k privátnímu clusteru .

Strategie postupného nasazení

Strategie postupného uvedení virtuálních počítačů se v každé iteraci aktualizuje až na pět cílů. maxParallel určí počet cílů, na které lze paralelně nasadit. Výběrové účty představují absolutní počet nebo procento cílů, které musí být kdykoli dostupné, s výjimkou nasazených cílů. Slouží také k určení podmínek úspěchu a selhání během nasazování.

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

Strategie testovacího nasazení

V dalším příkladu kanárová strategie pro AKS nejprve nasadí změny s 10procentním podem, po kterém následuje 20 procent a během sledování postRouteTrafficstavu . Pokud všechno půjde dobře, zvýší se na 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... 

Automatické vkládání kroků pomocí dekorátorů kanálu

Dekorátory kanálu je možné použít v úlohách nasazení k automatickému vložení libovolného vlastního kroku (například skeneru ohrožení zabezpečení) do každého spuštění každé úlohy nasazení zachytávaného životního cyklu. Vzhledem k tomu, že dekorátory kanálu je možné použít u všech kanálů v organizaci, je možné je použít jako součást vynucování postupů bezpečného nasazení.

Kromě toho je možné úlohy nasazení spustit jako úlohu kontejneru společně se službami, pokud jsou definované.

Podpora výstupních proměnných

Definujte výstupní proměnné v hookech životního cyklu úlohy nasazení a spotřebovávejte je v dalších podřízených krocích a úlohách ve stejné fázi.

Pokud chcete sdílet proměnné mezi fázemi, vypište artefakt v jedné fázi a pak ho spotřebujte v další fázi nebo použijte stageDependencies syntaxi popsanou v proměnných.

Při provádění strategií nasazení můžete přistupovat k výstupním proměnným napříč úlohami pomocí následující syntaxe.

  • Pro strategii runOnce : $[dependencies.<job-name>.outputs['<job-name>.<step-name>.<variable-name>']] (například $[dependencies.JobA.outputs['JobA.StepA.VariableA']])
  • Pro strategii runOnce plus resourceType: $[dependencies.<job-name>.outputs['Deploy_<resource-name>.<step-name>.<variable-name>']]. (například $[dependencies.JobA.outputs['Deploy_VM1.StepA.VariableA']])
  • Pro kanárovou strategii: $[dependencies.<job-name>.outputs['<lifecycle-hookname>_<increment-value>.<step-name>.<variable-name>']]
  • Pro strategii postupného zavádění : $[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

Pro úlohu runOnce zadejte název úlohy místo háku životního cyklu:

# 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

Při definování prostředí v úloze nasazení se syntaxe výstupní proměnné liší v závislosti na tom, jak se prostředí definuje. V tomto příkladu env1 používá zkrácený zápis a env2 zahrnuje úplnou syntaxi s definovaným typem prostředku.

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

Když vypíšete proměnnou z úlohy ve fázi 1, odkazování na ni z úlohy nasazení v další fázi použije jinou syntaxi v závislosti na tom, jestli chcete nastavit proměnnou nebo ji použít jako podmínku pro fázi.

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)

Při výstupu proměnné z úlohy nasazení použijte syntaxi stageDependencies k odkazování z další fáze (například $[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)

Další informace o tom, jak nastavit výstupní proměnnou s více úlohami

Často kladené dotazy

Kanál je zablokovaný se zprávou "Úloha čeká na vyřízení...". Jak to můžu opravit?

K tomu může dojít, když dojde ke konfliktu názvů mezi dvěma úlohami. Ověřte, že všechny úlohy nasazení ve stejné fázi mají jedinečný název a že názvy úloh a fází neobsahují klíčová slova. Pokud přejmenování problém nevyřeší, projděte si spuštění kanálu pro řešení potíží.

Podporují se dekorátory ve skupinách nasazení?

Ne. Ve skupinách nasazení nemůžete používat dekorátory.