자동화를 위한 Azure DevOps 변수 잠금 해제

Azure DevOps 파이프라인을 CI/CD 파이프라인 솔루션으로 사용하고 있다면, 빌드 및 릴리스에서 동적으로 구성 값을 관리해야 하는 상황에 부딪힐 수밖에 없을 것입니다. PowerShell 스크립트에 빌드 버전을 제공하거나, 빌드 작업에 동적 매개변수를 전달하거나, 빌드 및 릴리스 간에 문자열을 사용하는 경우에는 변수가 필요합니다.

다음과 같은 질문을 스스로 물었던 적이 있다면:

  • Azure DevOps 빌드 파이프라인 변수를 PowerShell 스크립트에서 어떻게 사용할 수 있을까요?
  • 빌드 및 릴리스 간에 변수를 공유하는 방법은 무엇인가요?
  • 미리 정의된 변수, 사용자 정의 변수 및 비밀 변수의 차이점은 무엇인가요?
  • 변수 그룹은 어떻게 작동하나요?

…그러면 운이 좋습니다! 이 기사에서는 이러한 각 질문에 대한 답변과 더불어 다른 내용도 제공할 것입니다.

이 기사의 끝에 Azure DevOps 빌드 변수가 Azure 파이프라인에서 어떻게 작동하는지 이해하게 될 것입니다!

Azure DevOps 파이프라인 변수란 무엇인가요?

변수의 구체적인 내용에 대해 자세히 알아보기 전에, 변수는 무엇이며 빌드 및 릴리스 파이프라인을 효율적으로 구축하고 자동화하는 데 어떻게 도움이 되는지 알아보겠습니다.

변수를 사용하면 여러 파이프라인의 다양한 부분에 데이터 조각을 전달할 수 있습니다. 변수는 파이프라인의 작업 흐름에서 변경될 수 있는 텍스트와 숫자를 저장하기에 좋습니다. 파이프라인에서는 스크립트와 YAML 정의에 값을 하드코딩하는 대신 거의 모든 곳에서 변수를 설정하고 읽을 수 있습니다.

참고: 이 문서는 YAML 파이프라인에만 초점을 맞춥니다. 기존의 클래식 파이프라인에 대한 정보는 다루지 않습니다. 또한, 웹 UI를 통해 변수를 다루는 방법도 약간의 예외를 제외하고는 다루지 않습니다. 엄격히 YAML에만 집중할 것입니다.

변수는 런타임에서 참조되고 일부는 정의됩니다(사용자 정의 변수 참조). 파이프라인이 작업을 시작할 때, 이러한 변수들을 관리하고 시스템의 다른 부분에 값을 전달하는 다양한 프로세스가 있습니다. 이 시스템은 빌드 정의와 스크립트를 매번 변경하지 않고도 동적으로 파이프라인 작업을 실행할 수 있는 방법을 제공합니다.

현재 변수 개념을 이해하지 못한다면 걱정하지 마세요. 이 문서의 나머지 부분에서 필요한 모든 내용을 알려드리겠습니다.

변수 환경

변수 자체에 대해 진입하기 전에, 먼저 Azure 파이프라인 변수 환경에 대해 알아보는 것이 중요합니다. 이 용어는 문서 전체에서 여러 참조를 볼 수 있습니다.

파이프라인 내에서는 변수와 상호작용할 수 있는 비공식적으로 두 개의 환경이 있습니다. 파이프라인 환경이라고 불리는 YAML 빌드 정의 내에서 변수를 다룰 수도 있고, 작업이라고 불리는 스크립트를 통해 스크립트 환경에서 변수를 다룰 수도 있습니다.

파이프라인 환경

YAML 빌드 정의 내에서 빌드 변수를 정의하거나 읽을 때, 이를 파이프라인 환경이라고 합니다. 예를 들어, 아래에서 YAML 빌드 정의 내에 정의된 변수 섹션인 variables를 볼 수 있습니다. 여기서는 변수가 foo로 설정되어 있습니다. 이 문맥에서 변수는 파이프라인 환경 내에서 정의되고 있습니다.

variables:
  foo: 'bar'

스크립트 환경

YAML 정의 자체나 스크립트 내에서 코드로부터 변수를 조작할 수도 있습니다. 이미 작성된 스크립트가 없는 경우, 아래에 표시된 대로 YAML 정의 내에서 변수를 정의하고 읽을 수 있습니다. 이 문맥에서 이러한 변수들과 작업하는 구문에 대해 나중에 배울 것입니다.

steps:
 - bash: ## 여기에서 변수 설정 및 가져오기

이와 비슷한 구문을 Bash 스크립트에 추가하고 실행하여 스크립트 환경 내에 머무를 수도 있습니다. 이는 동일한 개념입니다.

환경 변수

스크립트 환경 내에서 파이프라인 변수가 사용 가능하게 되면, 이는 환경 변수로 생성됩니다. 이러한 환경 변수는 선택한 언어의 일반적인 방법을 통해 액세스할 수 있습니다.

환경 변수로 노출된 파이프라인 변수는 항상 대문자로 표시되며, 점은 언더스코어로 대체됩니다. 예를 들어, 아래에서 각 스크립팅 언어가 어떻게 foo 파이프라인 변수에 접근하는지 볼 수 있습니다.

variables:
  foo: 'bar'
  • %FOO%
  • PowerShell $env:FOO
  • Bash 스크립트 – $FOO

파이프라인 “실행 단계”

파이프라인이 “실행”될 때, 그냥 “실행”되는 것뿐만 아니라 다양한 단계를 거칩니다. 포함된 단계와 마찬가지로, 파이프라인도 실행 중에 여러 단계를 거칩니다. Microsoft 문서에 공식 용어가 없어서 이를 “실행 단계”라고 부릅니다.

파이프라인이 트리거되면, 세 가지 대략적인 단계를 거치게 됩니다 – 대기열, 컴파일런타임. 이러한 맥락을 이해하는 것이 중요합니다. Microsoft 문서를 탐색하는 경우에는 이러한 용어에 대한 참조가 있을 것입니다.

대기열 시간

파이프라인이 대기열에 트리거되면 처음으로 거치는 단계입니다. 이 단계에서 파이프라인은 아직 시작되지 않았지만 에이전트가 사용 가능할 때 실행 준비가 된 상태입니다. 변수를 정의할 때 YAML 파일에서 정의하지 않고 대기열 시간에 사용할 수 있도록 설정할 수 있습니다.

다음과 같이 파이프라인이 처음으로 대기열에 추가될 때 대기열 시간에 변수를 정의할 수 있습니다. 이 변수가 추가되면 파이프라인에서 전역 변수로 사용할 수 있으며, YAML 파일에서 동일한 변수 이름으로 재정의할 수 있습니다.

Run Pipeline Azure DevOps option

컴파일

최종적으로, 파이프라인이 YAML 파일을 처리하고 스크립트 실행이 필요한 단계로 이동하면 파이프라인은 컴파일 “단계”에 있습니다. 이 문맥에서, 에이전트는 스크립트 단계에서 정의된 코드를 실행합니다.

런타임

다음 단계는 런타임입니다. 이 단계에서는 YAML 파일이 처리됩니다. 이 단계에서는 각 스테이지, 작업 및 단계가 처리되지만 스크립트는 실행되지 않습니다.변수 확장

이해해야 할 또 다른 중요한 주제는 변수 확장입니다. 가장 간단하게 말하면, 변수 확장은 변수가 정적 값을 반환하는 것을 의미합니다. 변수는 확장되어 해당 값을 나타냅니다. 변수를 읽을 때 이 확장은 자동으로 수행되지만, 이 확장은 파이프라인 실행 중에 다른 시간에 수행될 수 있으므로 주의해야 할 수도 있습니다.

변수 확장 및 컴파일 vs. 런타임의 이 개념은 변수 구문을 이해하는 데 많이 사용됩니다.앞에서 배운대로, 파이프라인은 실행될 때 다른 “단계”를 거칩니다. 변수 확장을 문제 해결할 때 이러한 단계를 알고 있어야 할 것입니다.

아래 예제를 살펴보면 됩니다. 이러한 “단계”의 개념은 변수 환경과 밀접한 관련이 있습니다.

steps:
  # 스크립트에서 FOO를 "some value"로 설정하고 다음 단계에서도 그 값을 사용합니다
  - bash: |
      FOO="runtime value"
      echo "##vso[task.setvariable variable=FOO]$FOO"

  # "컴파일 시간"에 $() 구문을 사용하여 파이프라인이 변수를 확장합니다
  - bash: |
      echo "$(FOO)"

  # "런타임"에서 스크립트 컨텍스트에서 환경 변수를 사용하면 bash가 변수를 확장합니다
  - bash: |
      echo "$FOO"

파이프라인 실행이 시작될 때 변수는 한 번 확장되며, 각 단계의 시작에서 다시 확장됩니다. 아래는 이 동작의 간단한 예입니다.

jobs:
- job: build
  variables:
  - foo: bar 
  steps:
    - bash: |
        echo $(foo)            # This will be bar
        echo '##vso[task.setvariable variable=foo]baz'
        echo $(foo)            # This will also be bar, $(foo) expands before the step
    - bash: echo $(foo)        # 이것은 baz가 될 것입니다. 변수는 단계 바로 앞에서 확장됩니다.

변수 구문

배운 대로, 파이프라인 환경과 스크립트 환경의 두 가지 “환경”에서 변수를 설정하거나 읽을 수 있습니다. 각 환경에서 변수를 참조하는 방법은 약간 다릅니다. 주의해야 할 세세한 사항이 몇 가지 있습니다.

파이프라인 변수

파이프라인 변수는 YAML 빌드 정의에서 참조되며, 매크로, 템플릿 표현식 및 런타임 표현식 세 가지 다른 구문 방법을 통해 참조할 수 있습니다.

매크로 구문

가장 일반적인 구문은 매크로 구문입니다. 매크로 구문은 변수의 값을 $(foo) 형식으로 참조합니다. 괄호는 런타임에 평가되는 표현식을 나타냅니다.

Azure 파이프라인이 매크로 표현식으로 정의된 변수를 처리할 때, 표현식을 변수의 내용으로 대체합니다. 매크로 구문으로 변수를 정의할 때, <변수 이름>: $(<변수 값>)과 같은 패턴을 따릅니다. 예: foo: $(bar).

매크로 구문과 함께 변수를 참조하려고 시도하고 값이 존재하지 않으면, 해당 변수는 단순히 존재하지 않습니다. 이 동작은 구문 유형에 따라 약간 다릅니다.

템플릿 표현식 구문

템플릿 식이라고 불리는 다른 유형의 변수 구문도 있습니다. 이 방식으로 파이프라인 변수를 정의하는 것은 ${{ variables.foo }} : ${{ variables.bar }}와 같은 형태를 취합니다. 보시다시피, 매크로 구문보다 조금 더 길게 작성됩니다.

템플릿 식 구문에는 추가 기능이 있습니다. 이 구문을 사용하여 템플릿 매개변수를 확장할 수도 있습니다. 템플릿 식 구문으로 정의된 변수가 참조되면, 파이프라인은 매크로 구문과 달리 null 값 대신 빈 문자열을 반환합니다.

템플릿 식 변수는 컴파일 시간에 처리되고, 실행 시간에 덮어쓰기됩니다(정의된 경우).

실행 시간 식 구문

구문 유형을 제안한 실행 시간 식 변수는 실행 시에만 확장됩니다. 이러한 유형의 변수는 $[variables.foo]와 같은 형식으로 표시됩니다. 템플릿 식 구문 변수와 마찬가지로, 이러한 유형의 변수는 대체되지 않으면 빈 문자열을 반환합니다.

매크로 구문과 마찬가지로, 실행 시간 식 구문은 정의 시 변수 이름이 정의 왼쪽에 있어야 합니다. 예를 들어 foo: $[variables.bar]입니다.

스크립트 변수

스크립트 내에서 변수를 다루는 방법은 파이프라인 변수와 약간 다릅니다. 작업 스크립트에서 노출된 파이프라인 변수를 정의하고 참조하는 방법은 로그 명령 구문 또는 환경 변수를 사용하여 수행할 수 있습니다.

로그 명령어

스크립트에서 파이프라인 변수를 정의하고 참조하는 한 가지 방법은 로깅 명령어 구문을 사용하는 것입니다. 이 구문은 다소 복잡하지만 특정 상황에서 필요하다는 것을 배우게 될 것입니다. 이러한 방식으로 정의된 변수는 스크립트에서 문자열로 정의되어야 합니다.

아래와 같이 로깅 명령어 구문을 사용하여 값을 ‘bar’로 설정하는 ‘foo’라는 변수를 정의하는 것은 다음과 같습니다.

"##vso[task.setvariable variable=foo;]bar"

I could not find a way to get the value of variables using logging commands. If this exists, let me know!

환경 변수

파이프라인 변수가 스크립트에서 환경 변수로 변환되면 변수 이름이 약간 변경됩니다. 변수 이름이 대문자로 변하고 마침표는 밑줄로 바뀌는 것을 알 수 있습니다. 많은 미리 정의된 또는 시스템 변수에는 마침표가 포함되어 있습니다.

예를 들어, ‘[foo.bar](<http://foo.bar>)’라는 파이프라인 변수가 정의된 경우, PowerShell에서는 ‘$env:FOO_BAR’ 또는 Bash에서는 ‘$FOO_BAR’와 같은 스크립트의 기본 환경 변수 참조 방법을 통해 해당 변수를 참조할 수 있습니다.

위의 스크립트 환경 섹션에서 환경 변수에 대해 더 자세히 다루었습니다.

변수 범위

A pipeline has various stages, tasks and jobs running. Many areas have predefined variable scopes. A scope is namespace where when a variable is defined, its value can be referenced.

계층 구조에서 실질적으로 세 가지 다른 변수 범위가 있습니다. 이는 다음과 같이 정의된 변수에 해당합니다:

  • 파이프라인의 모든 작업에서 사용할 수 있는 루트 수준의 변수
  • 특정 단계에서만 사용할 수 있는 단계 수준의 변수
  • 특정 작업에서만 사용할 수 있는 작업 수준의 변수

“낮은” 수준에서 정의된 작업과 같은 변수는 단계 및 루트 수준에서 정의된 동일한 변수를 무시합니다. 예를 들어, 단계 수준에서 정의된 변수는 작업 수준에서 정의된 변수를 무시하지만 작업 수준에서 정의된 변수에 의해 덮어쓰입니다.

아래에서 각 범위가 사용되는 YAML 빌드 정의의 예를 볼 수 있습니다.

variables:
  global_variable: value  # 모든 단계 및 작업에서 사용 가능한 전역 변수입니다

stages:
- stage: Build
  variables:
    stage_variable1: value3 # 빌드 단계와 모든 작업에서 사용 가능합니다
  jobs:
  - job: BuildJob
    variables:
      job_variable1: value1    # 이 변수는 빌드 작업에서만 사용 가능합니다
    steps:
    - bash: echo $(stage_variable1) ## 작동합니다
    - bash: echo $(global_variable) ## 작동합니다
    - bash: echo $(job_variable1) ## 작동합니다

변수 우선순위

가끔은 동일한 이름을 가진 변수가 여러 범위에서 설정된 상황을 볼 수 있습니다. 이런 경우에는 해당 변수의 값이 특정 순서에 따라 덮어쓰여지며 가장 가까운 “동작”에 우선순위가 부여됩니다.

아래에서 작업 내에서 설정된 변수로 시작하여 덮어쓰여질 변수의 순서를 볼 수 있습니다. 이것이 가장 큰 우선순위를 가집니다.

  1. YAML 파일에서 설정된 작업 수준에서 설정된 변수
  2. YAML 파일에서 설정된 단계 수준에서 설정된 변수
  3. YAML 파일에서 설정된 파이프라인 수준(전역)에서 설정된 변수
  4. 대기 시간에 설정된 변수
  5. 파이프라인 설정 UI에서 설정된 파이프라인 변수입니다

예를 들어, 아래의 YAML 정의를 살펴보십시오. 이 예제에서는 동일한 변수가 여러 곳에서 설정되지만 최종적으로 작업에서 정의된 값으로 끝납니다. 각 작업에서 변수의 값은 파이프라인이 작업으로 이동할 때마다 덮어씌워집니다.

variables:
  foo: 'global variable'

stages:
- stage: build
  variables:
   - name: foo
     value: 'defined at stage level'

  jobs:
  - job: compile
    variables:
    - name: foo
      value: 'defined at job level'
    steps:
      - bash: echo $(foo) # 이 값은 작업 수준에서 정의됩니다.

변수 유형

지금까지 이 기사에서 변수가 무엇인지, 어떻게 보이는지, 실행될 수 있는 문맥 등에 대해 배웠습니다. 그러나 우리가 다루지 않은 것은 모든 변수가 동일하지 않다는 것입니다. 파이프라인을 시작할 때 이미 존재하는 일부 변수는 변경할 수 없지만 다른 변수는 원하는 대로 생성, 변경 및 제거할 수 있습니다.

일반적으로 변수에는 네 가지 유형이 있습니다 – 미리 정의된 또는 시스템 변수, 사용자 정의 변수, 출력 변수 및 비밀 변수입니다. 각 유형의 변수를 이해하기 위해 각각에 대해 자세히 알아보겠습니다.

미리 정의된 변수

모든 빌드 및 릴리스 내에서는 기본적으로 존재하는 다양한 변수를 찾을 수 있습니다. 이러한 변수는 미리 정의된 또는 시스템 변수라고 불립니다. 미리 정의된 변수는 모두 읽기 전용이며, 다른 유형의 변수와 마찬가지로 간단한 문자열과 숫자를 나타냅니다.

Azure 파이프라인은 빌드를 실행하는 소프트웨어 에이전트, 배포가 실행될 때 생성되는 작업 및 기타 다양한 정보 등 여러 구성 요소로 구성됩니다. 이러한 모든 영역을 표현하기 위해 미리 정의된 변수는 비공식적으로 다섯 가지로 나뉘어집니다:

  • 에이전트
  • 빌드
  • 파이프라인
  • 배포 작업
  • 시스템

이 다섯 가지 범주 각각에 여러 변수가 퍼져 있습니다. 이 글에서는 이러한 변수들 중 일부에 대해서만 알아볼 것입니다. 모든 미리 정의된 변수의 목록을 원한다면 Microsoft 문서를 확인해보세요.

사용자 정의 변수

YAML 정의나 스크립트를 통해 변수를 생성하면 사용자 정의 변수를 생성하는 것입니다. 사용자 정의 변수는 단순히 사용자인 여러분이 파이프라인에서 정의하고 사용하는 모든 변수입니다. 이러한 변수에는 거의 모든 이름을 사용할 수 있지만 예외 몇 가지가 있습니다.

endpoint, input, secret 또는 securefile로 시작하는 변수는 정의할 수 없습니다. 이러한 레이블은 시스템 사용을 위해 예약되어 있으며 대소문자를 구분하지 않습니다.

또한, 정의하는 변수는 문자, 숫자, 점 또는 밑줄 문자로만 구성되어야 합니다. 이 형식을 따르지 않는 변수를 정의하면 YAML 빌드 정의가 작동하지 않습니다.

출력 변수

A build definition contains one or more tasks. Sometimes a task sends a variable out to be made available to downstream steps and jobs within the same stage. These types of variables are called output variables.

출력 변수는 파이프라인의 구성 요소 간에 정보를 공유하는 데 사용됩니다. 예를 들어, 한 작업이 데이터베이스에서 값을 조회하고 다음 작업에서 결과를 반환해야 할 경우 출력 변수를 사용할 수 있습니다. 이렇게하면 매번 데이터베이스를 조회할 필요가 없습니다. 대신에 변수를 참조하기만 하면 됩니다.

참고: 출력 변수는 특정 단계에 대해 범위가 지정됩니다. 예를 들어, “빌드” 단계와 “테스트” 단계에서 출력 변수가 모두 사용 가능하다고 기대하지 마십시오.

비밀 변수

마지막 유형의 변수는 비밀 변수입니다. 기술적으로, 이것은 독립된 유형이 아니기 때문에 시스템 또는 사용자 정의 변수일 수 있습니다. 그러나 비밀 변수는 다른 변수와 다르게 처리되므로 별도의 범주로 구분해야 합니다.

A secret variable is a standard variable that’s encrypted. Secret variables typically contain sensitive information like API keys, passwords, etc. These variables are encrypted at rest with a 2048-bit RSA key and are available on the agent for all tasks and scripts to use.

– YAML 파일 내에서 비밀 변수를 정의하지 마십시오.
– 비밀을 출력 변수나 로깅 정보로 반환하지 마십시오.

비밀 변수는 파이프라인 편집기에서 정의해야 합니다. 이렇게 하면 비밀 변수가 전역 수준에서 범위가 지정되어 파이프라인의 작업에서 사용할 수 있게 됩니다.

비밀 값은 로그에서 마스크 처리되지만 완전히 숨겨지지는 않습니다. 따라서 YAML 파일에 포함시키지 않는 것이 중요합니다. 또한 비밀로 처리되어야 하는 “구조화된” 데이터를 비밀로 포함시키지 말아야 합니다. 예를 들어 { "foo": "bar" }를 비밀로 설정한 경우, bar가 로그에서 마스크 처리되지 않습니다.

비밀은 자동으로 복호화되어 환경 변수에 매핑되지 않습니다. 비밀 변수를 정의한 경우, 예를 들어 PowerShell 스크립트에서 $env:FOO를 통해 사용 가능하다고 기대하지 마십시오.

변수 그룹

마지막으로, 변수 그룹에 대해 이야기하겠습니다. 변수 그룹은 하나로 참조할 수 있는 변수들의 “그룹”입니다. 변수 그룹의 주요 목적은 여러 파이프라인에서 사용 가능하도록 값을 저장하는 것입니다.

변수 그룹은 YAML 파일에서 정의되지 않습니다. 대신, 라이브러리 페이지의 파이프라인에서 정의됩니다.

변수 그룹을 사용하여 여러 파이프라인에서 제어하고 사용할 값을 저장할 수 있습니다. 또한 변수 그룹을 사용하여 YAML 파이프라인으로 전달해야 하는 비밀과 기타 값을 저장할 수도 있습니다. 변수 그룹은 아래와 같이 라이브러리 페이지의 파이프라인에서 정의하고 관리됩니다.

Viewing variable groups

파이프라인 라이브러리에서 정의한 후, 아래 구문을 사용하여 YAML 파일에서 해당 변수 그룹에 액세스할 수 있습니다.

variables:
- group: group1

변수 그룹은 기본적으로 모든 파이프라인에서 사용할 수 없습니다. 이 설정은 그룹을 생성할 때 사용할 수 있습니다. 파이프라인은 변수 그룹을 사용할 수 있도록 인증되어야 합니다.

변수 그룹을 YAML 파일에서 액세스할 수 있게 되면, 그룹 내부의 변수에 다른 변수와 동일한 방식으로 액세스할 수 있습니다. 변수 그룹의 이름은 그룹 내 변수를 참조할 때 사용되지 않습니다.

예를 들어, group1이라는 변수 그룹을 정의하고 내부에 foo라는 변수가 있다면, 다른 변수와 마찬가지로 foo 변수를 참조할 수 있습니다. 예: $(foo).

변수 그룹에서 정의된 비밀 변수는 직접 스크립트를 통해 액세스할 수 없습니다. 대신, 작업에 인수로 전달해야 합니다.

변수 그룹 내부의 변수를 변경하면, 해당 그룹을 사용할 수 있는 모든 파이프라인에서 변경 사항이 자동으로 적용됩니다.

요약

이제 Azure 파이프라인 변수에 대한 튼튼한 지식을 갖게 되었어야 합니다. 이 글에서 변수에 관련된 거의 모든 개념을 배웠습니다! 이제 알아낸 지식을 Azure DevOps 파이프라인에 적용하고 모든 작업을 자동화하세요!

Source:
https://adamtheautomator.com/azure-devops-variables/