Deployment jobs(배포 작업)

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

Important

  • 작업 및 스테이지 이름에는 키워드(keyword)(예: deployment)를 포함할 수 없습니다.
  • 단계의 각 작업에는 고유한 이름이 있어야 합니다.

YAML 파이프라인에서는 배포 작업이라는 특수 유형의 작업에 배포 단계를 배치하는 것이 좋습니다. 배포 작업은 환경에 대해 순차적으로 실행되는 단계 컬렉션입니다. 배포 작업과 기존 작업은 동일한 단계에 존재할 수 있습니다. Azure DevOps는 runOnce, 롤링카나리아 전략을 지원합니다.

배포 작업은 다음과 같은 이점을 제공합니다.

  • 배포 기록: 감사를 위해 특정 리소스 및 배포 상태에 이르기까지 파이프라인 전반에 걸친 배포 기록을 가져옵니다.
  • 배포 전략 적용: 애플리케이션이 배포되는 방식을 정의합니다.

배포 작업은 원본 리포지토리를 자동으로 복제하지 않습니다. 를 사용하여 작업 checkout: self내의 원본 리포지토리를 검사 수 있습니다.

참고 항목

이 문서에서는 배포 작업을 사용한 배포에 중점을 둡니다. 파이프라인을 사용하여 Azure에 배포하는 방법을 알아보려면 Azure에 배포 개요를 참조하세요.

스키마

배포 작업을 지정하는 전체 구문은 다음과 같습니다.

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 ]

속성에 사용할 수 있는 보다 자세한 대체 구문이 environment 있습니다.

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.

가상 머신의 경우 풀을 정의할 필요가 없습니다. 가상 머신 리소스를 사용하여 배포 작업에서 정의하는 모든 단계는 풀의 에이전트가 아닌 해당 가상 머신에 대해 실행됩니다. Kubernetes와 같은 다른 리소스 유형의 경우 해당 컴퓨터에서 작업을 실행할 수 있도록 풀을 정의해야 합니다.

배포 전략

애플리케이션 업데이트를 배포하는 경우 업데이트를 제공하는 데 사용하는 기술은 다음과 같습니다.

  • 초기화를 사용합니다.
  • 업데이트를 배포합니다.
  • 업데이트된 버전으로 트래픽을 라우팅합니다.
  • 트래픽을 라우팅한 후 업데이트된 버전을 테스트합니다.
  • 오류가 발생하면 단계를 실행하여 마지막으로 알려진 정상 버전으로 복원합니다.

배포하는 동안 단계를 실행할 수 있는 수명 주기 후크를 사용하여 이를 달성합니다. 각 수명 주기 후크는 특성에 pool 따라 에이전트 작업 또는 서버 작업(또는 향후 컨테이너 또는 유효성 검사 작업)으로 확인됩니다. 기본적으로 수명 주기 후크는 작업에서 지정한 deployment 것을 pool 상속합니다.

배포 작업은 $(Pipeline.Workspace) 시스템 변수를 사용합니다.

수명 주기 후크에 대한 설명

preDeploy: 애플리케이션 배포가 시작되기 전에 리소스를 초기화하는 단계를 실행하는 데 사용됩니다.

deploy: 애플리케이션을 배포하는 단계를 실행하는 데 사용됩니다. 아티팩트 다운로드 작업은 배포 작업에 대한 후크에 deploy 만 자동으로 삽입됩니다. 아티팩트 다운로드를 중지하려면 파이프라인 아티팩트 다운로드 작업을 지정하여 다운로드할 특정 아티팩트 사용 - download: none 또는 선택

routeTraffic: 업데이트된 버전에 대한 트래픽을 제공하는 단계를 실행하는 데 사용됩니다.

postRouteTraffic: 트래픽이 라우팅된 후 단계를 실행하는 데 사용됩니다. 일반적으로 이러한 작업은 정의된 간격 동안 업데이트된 버전의 상태를 모니터링합니다.

on: failure또는 on: success: 롤백 작업 또는 클린 단계를 실행하는 데 사용됩니다.

RunOnce 배포 전략

runOnce는 모든 수명 주기 후크, 즉preDeploydeploy, routeTrafficpostRouteTraffic한 번 실행되는 가장 간단한 배포 전략입니다. 그런 다음, on:success 또는 on:failure가 실행됩니다.

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

자체 호스팅 에이전트를 사용하는 경우 작업 영역 클린 옵션을 사용하여 배포 작업 영역을 클린 수 있습니다.

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

롤링 배포 전략

롤링 배포는 이전 버전의 애플리케이션 인스턴스를 각 반복에서 고정된 가상 머신 집합(롤링 세트)의 새 버전의 애플리케이션 인스턴스로 바꿉니다.

현재는 VM 리소스에 대한 롤링 전략만 지원합니다.

예를 들어 롤링 배포는 일반적으로 다음 배포 집합으로 진행하기 전에 각 가상 머신 집합의 배포가 완료되기를 기다립니다. 각 반복 후 상태 검사 수행할 수 있으며 중요한 문제가 발생하면 롤링 배포를 중지할 수 있습니다.

롤링 배포는 노드 아래에 strategy: 키워드(keyword) rolling: 지정하여 구성할 수 있습니다. 변수는 strategy.name 전략의 이름을 사용하여 이 전략 블록에서 사용할 수 있습니다. 이 경우 롤링합니다.

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

모든 수명 주기 후크가 지원되며 각 VM에서 실행되도록 수명 주기 후크 작업이 만들어집니다.

preDeploy, deploy, routeTrafficpostRouteTraffic 로 정의된 maxParallel일괄 처리 크기당 한 번 실행됩니다. 그런 다음, on: success 또는 on: failure가 실행됩니다.

를 사용하면 병렬로 maxParallel: <# or % of VMs>배포할 가상 머신 대상의 수/비율을 제어할 수 있습니다. 이렇게 하면 앱이 이러한 컴퓨터에서 실행되고 나머지 컴퓨터에서 배포가 진행되는 동안 요청을 처리할 수 있으므로 전체 가동 중지 시간이 줄어듭니다.

참고 항목

이 기능에는 몇 가지 알려진 간격이 있습니다. 예를 들어 스테이지를 다시 시도하면 실패한 대상뿐만 아니라 모든 VM에서 배포를 다시 실행합니다.

카나리아 배포 전략

카나리아 배포 전략은 새 버전의 애플리케이션을 배포하는 데 관련된 위험을 완화하는 데 도움이 되는 고급 배포 전략입니다. 이 전략을 사용하면 먼저 서버의 작은 하위 집합에 변경 내용을 롤아웃할 수 있습니다. 새 버전에 자신감이 생기면 인프라의 더 많은 서버로 릴리스하고 더 많은 트래픽을 해당 버전으로 라우팅할 수 있습니다.

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

카나리아 배포 전략은 수명 주기 후크(한 번 실행)를 지원하고 preDeploy , routeTrafficpostRouteTraffic 수명 주기 후크를 사용하여 반복deploy합니다. 그런 다음, 후크 또는 failure 후크로 success 종료합니다.

이 전략에서 사용할 수 있는 변수는 다음과 같습니다.

strategy.name: 전략의 이름입니다. 예를 들어 카나리아입니다.
strategy.action: Kubernetes 클러스터에서 수행할 작업입니다. 예를 들어 배포, 승격 또는 거부합니다.
strategy.increment: 현재 상호 작용에 사용되는 증분 값입니다. 이 변수는 수 routeTrafficpostRouteTraffic 명 주기 후크에서deploy만 사용할 수 있습니다.

예제

RunOnce 배포 전략

다음 예제 YAML 코드 조각은 배포 전략을 사용하여 배포 작업을 간단하게 사용하는 방법을 runOnce 보여 줍니다. 이 예제에는 검사 단계가 포함되어 있습니다.


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

이 작업을 실행할 때마다 환경에 대해 smarthotel-dev 배포 기록이 기록됩니다.

참고 항목

  • 또한 빈 리소스가 있는 환경을 만들고 이를 추상 셸로 사용하여 이전 예제와 같이 배포 기록을 기록할 수도 있습니다.

다음 예제에서는 파이프라인이 배포 작업의 대상으로 사용할 환경과 리소스를 모두 참조하는 방법을 보여 줍니다.

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)

이 방법은 다음과 같은 이점이 있습니다.

  • 환경 내의 모든 리소스에 대한 기록을 기록하는 것이 아니라 환경 내의 특정 리소스에 대한 배포 기록을 기록합니다.
  • 배포 작업의 단계는 배포 작업이 환경에 연결되므로 리소스의 연결 세부 정보(이 경우 Kubernetes 네임스페이스smarthotel-dev.bookings)를 자동으로 상속합니다. 이는 작업의 여러 단계에 대해 동일한 연결 세부 정보가 설정된 경우에 유용합니다.

롤링 배포 전략

VM에 대한 롤링 전략은 각 반복에서 최대 5개의 대상을 업데이트합니다. maxParallel 는 병렬로 배포할 수 있는 대상 수를 결정합니다. 선택 영역은 배포되는 대상을 제외하고 언제든지 다시 사용할 수 기본 대상의 절대 수 또는 백분율을 차지합니다. 배포 중에 성공 및 실패 조건을 확인하는 데도 사용됩니다.

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

카나리아 배포 전략

다음 예제에서 AKS에 대한 카나리아 전략은 먼저 10%의 Pod를 사용하여 변경 내용을 배포하고, 그 다음에 20%를 배포하고, 그 다음에는 postRouteTraffic상태를 모니터링합니다. 모든 것이 잘되면 100%로 승격됩니다.

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

파이프라인 데코레이터를 사용하여 자동으로 단계 삽입

파이프라인 데코레이터 는 배포 작업에서 모든 사용자 지정 단계(예: 취약성 스캐너)를 모든 배포 작업의 모든 수명 주기 후크 실행에 자동으로 삽입하는 데 사용할 수 있습니다. 파이프라인 데코레이터는 조직의 모든 파이프라인에 적용할 수 있으므로 안전한 배포 사례를 적용하는 일부로 적용할 수 있습니다.

또한 배포 작업은 정의된 경우 서비스 사이드카함께 컨테이너 작업으로 실행할 수 있습니다.

출력 변수 지원

배포 작업의 수명 주기 후크에서 출력 변수를 정의하고 동일한 단계 내의 다른 다운스트림 단계 및 작업에서 사용합니다.

단계 간에 변수를 공유하려면 아티팩트를 한 단계로 출력한 다음 후속 단계에서 사용하거나 변수설명된 구문을 사용합니다stageDependencies.

배포 전략을 실행하는 동안 다음 구문을 사용하여 작업 전체의 출력 변수에 액세스할 수 있습니다.

  • runOnce 전략의 경우: (예: $[dependencies.<job-name>.outputs['<job-name>.<step-name>.<variable-name>']]$[dependencies.JobA.outputs['JobA.StepA.VariableA']])
  • runOnce 전략 및 resourceType의 경우: $[dependencies.<job-name>.outputs['<job-name>_<resource-name>.<step-name>.<variable-name>']]. (예: $[dependencies.JobA.outputs['Deploy_VM1.StepA.VariableA']])
  • 카나리아 전략의 경우:$[dependencies.<job-name>.outputs['<lifecycle-hookname>_<increment-value>.<step-name>.<variable-name>']]
  • 롤링 전략의 경우:$[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

runOnce 작업의 경우 수명 주기 후크 대신 작업의 이름을 지정합니다.

# 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

배포 작업에서 환경을 정의하는 경우 출력 변수의 구문은 환경이 정의되는 방식에 따라 달라집니다. 이 예제 env1 에서는 약식 표기법을 env2 사용하고 정의된 리소스 형식의 전체 구문을 포함합니다.

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

배포 작업에서 변수를 출력하는 경우 다음 작업에서 변수를 참조하면 변수를 설정하거나 스테이지의 조건으로 사용할지 여부에 따라 다른 구문을 사용합니다.

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)

다중 작업 출력 변수를 설정하는 방법에 대해 자세히 알아보기

FAQ

내 파이프라인이 "작업이 보류 중입니다..."라는 메시지와 함께 중단되었습니다. 이 문제를 해결하려면 어떻게 해야 하나요?

이 작업은 두 작업 간에 이름이 충돌할 때 발생할 수 있습니다. 동일한 단계의 모든 배포 작업에 고유한 이름이 있고 작업 및 스테이지 이름에 키워드(keyword) 포함되어 있지 않은지 확인합니다. 이름을 바꾸면 문제가 해결되지 않으면 파이프라인 실행 문제 해결을 검토합니다.

배포 그룹에서 데코레이터가 지원되는가요?

아니요. 배포 그룹에서는 데코레이터를 사용할 수 없습니다.