다른 파일에서 CI/CD 구성 사용하기

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-Managed, GitLab Dedicated

CI/CD 작업에서 외부 YAML 파일을 포함하려면 include을 사용할 수 있습니다.

단일 구성 파일 포함

단일 구성 파일을 포함하려면 다음 중 하나의 구문 옵션을 사용하세요:

  • 단일 파일을 사용하려면 단순히 include를 사용합니다. 만약 로컬 파일이면 include:local과 동일합니다. 원격 파일인 경우 include:remote와 같습니다.

    include: '/templates/.after-script-template.yml'
    

구성 파일 배열 포함

구성 파일 배열을 포함할 수 있습니다:

  • include 유형을 지정하지 않으면, 각 배열 항목은 include:local 또는 include:remote로 자동 설정됩니다.

    include:
      - 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
      - '/templates/.after-script-template.yml'
    
  • 단일 항목 배열을 정의할 수 있습니다:

    include:
      - remote: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
    
  • 배열을 정의하고 여러 include 유형을 명시적으로 지정할 수 있습니다:

    include:
      - remote: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
      - local: '/templates/.after-script-template.yml'
      - template: Auto-DevOps.gitlab-ci.yml
    
  • 기본 및 특정 include 유형을 조합하는 배열을 정의할 수 있습니다:

    include:
      - 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml'
      - '/templates/.after-script-template.yml'
      - template: Auto-DevOps.gitlab-ci.yml
      - project: 'my-group/my-project'
        ref: main
        file: '/templates/.gitlab-ci-template.yml'
    

포함된 구성 파일의 default 구성 사용하기

구성 파일에 default 섹션을 정의할 수 있습니다. include 키워드로 default 섹션을 사용하면 기본값이 파이프라인의 모든 작업에 적용됩니다.

예를 들어, before_script과 함께 default 섹션을 사용할 수 있습니다.

이름이 /templates/.before-script-template.yml인 사용자 정의 구성 파일의 내용:

default:
  before_script: 
    - apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs
    - gem install bundler --no-document 
    - bundle install --jobs $(nproc) "${FLAGS[@]}"

.gitlab-ci.yml의 내용:

include: '/templates/.before-script-template.yml'

rspec1:
  script:
    - bundle exec rspec

rspec2:
  script:
    - bundle exec rspec

기본 before_script 명령은 script 명령 앞에 있는 rspec 작업에서 실행됩니다.

포함된 구성 값 오버라이드하기

include 키워드를 사용할 때 포함된 구성 값들을 오버라이드하여 파이프라인 요구 사항에 맞게 조정할 수 있습니다.

다음 예제는 .gitlab-ci.yml 파일에서 사용자 정의된 include 파일입니다. YAML으로 정의된 특정 변수 및 production 작업의 세부 정보가 오버라이드되었습니다.

autodevops-template.yml이라는 사용자 정의 구성 파일의 내용:

variables:
  POSTGRES_USER: user
  POSTGRES_PASSWORD: testing_password
  POSTGRES_DB: $CI_ENVIRONMENT_SLUG

production:
  stage: production
  script:
    - install_dependencies
    - deploy
  environment:
    name: production
    url: https://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

.gitlab-ci.yml의 내용:

include: 'https://company.com/autodevops-template.yml'

default:
  image: alpine:latest

variables:
  POSTGRES_USER: root
  POSTGRES_PASSWORD: secure_password

stages:
  - build
  - test
  - production

production:
  environment:
    url: https://domain.com

.gitlab-ci.yml 파일에서 정의된 POSTGRES_USERPOSTGRES_PASSWORD 변수와 production 작업의 environment:urlautodevops-template.yml 파일에 정의된 값보다 우선합니다. 나머지 키워드는 변경되지 않습니다. 이 방법을 Merge이라고 합니다.

include의 Merge 방법

include 구성은 다음과 같은 프로세스로 주 구성 파일과 Merge됩니다:

  • 포함된 파일은 구성 파일에서 정의된 순서대로 읽혀지며, 포함된 구성이 동일한 순서로 Merge됩니다.
  • 포함된 파일도 include를 사용하는 경우, 해당 중첩 include 구성은 먼저 Merge됩니다(재귀적으로).
  • 매개변수가 겹치는 경우, 포함된 파일의 구성을 Merge할 때 가장 마지막에 포함된 파일이 우선합니다.
  • include로 추가된 모든 구성을 함께 Merge한 후, 주 구성과 포함된 구성을 Merge합니다.

이 Merge 방법은 해시 맵이 구성의 어떠한 깊이에서도 Merge되는 _딥 Merge_입니다. “A” 구성(지금까지 Merge된 구성을 포함하는)과 “B” 구성(다음 조각의 구성)을 Merge할 때 키와 값은 다음과 같이 처리됩니다:

  • 키가 A에만 존재하는 경우, A의 키와 값을 사용합니다.
  • A와 B에 모두 존재하고 값이 해시 맵인 경우, 해당 해시 맵을 Merge합니다.
  • A와 B에 모두 존재하고 값 중 하나가 해시 맵이 아닌 경우, B의 값을 사용합니다.
  • 그 외에는 B의 키와 값이 사용됩니다.

예를 들어, 두 파일로 이루어진 구성을 사용하는 경우:

  • .gitlab-ci.yml 파일:

    include: 'common.yml'
      
    variables:
      POSTGRES_USER: username
      
    test:
      rules:
        - if: $CI_PIPELINE_SOURCE == "merge_request_event"
          when: manual
      artifacts:
        reports:
          junit: rspec.xml
    
  • common.yml 파일:

    variables:
      POSTGRES_USER: common_username
      POSTGRES_PASSWORD: testing_password
      
    test:
      rules:
        - when: never
      script:
        - echo LOGIN=${POSTGRES_USER} > deploy.env
        - rake spec
      artifacts:
        reports:
          dotenv: deploy.env
    

복합된 결과는 다음과 같습니다:

variables:
  POSTGRES_USER: username
  POSTGRES_PASSWORD: testing_password

test:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: manual
  script:
    - echo LOGIN=${POSTGRES_USER} > deploy.env
    - rake spec
  artifacts:
    reports:
      junit: rspec.xml
      dotenv: deploy.env

이 예제에서:

  • 변수는 모든 파일이 Merge된 후에 평가됩니다. 포함된 파일의 작업은 다른 파일에서 정의된 변수 값을 사용할 수 있습니다.
  • rules은 배열이므로 Merge할 수 없습니다. 최상위 파일이 우선합니다.
  • artifacts는 해시 맵이므로 깊은 Merge이 가능합니다.

포함된 구성 배열 오버라이드하기

확장 및 오버라이드를 사용하여 포함된 템플릿의 구성을 수정할 수는 있지만 배열의 개별 항목을 추가하거나 수정할 수는 없습니다. 예를 들어, 확장된 production 작업의 script 배열에 추가적인 notify_owner 명령을 추가하려는 경우:

autodevops-template.yml의 내용:

production:
  stage: production
  script:
    - install_dependencies
    - deploy

.gitlab-ci.yml의 내용:

include: 'autodevops-template.yml'

stages:
  - production

production:
  script:
    - install_dependencies
    - deploy
    - notify_owner

만약 .gitlab-ci.yml 파일에서 install_dependenciesdeploy가 반복되지 않으면, production 작업은 스크립트에 notify_owner만 포함하게 됩니다.

중첩된 include 사용

구성 파일에 중첩된 include 섹션을 사용하여 다른 구성 파일에 포함된 구성 파일을 중첩시킬 수 있습니다. 예를 들어, include 키워드가 세 번 중첩된 경우:

.gitlab-ci.yml의 내용:

include:
  - local: /.gitlab-ci/another-config.yml

/.gitlab-ci/another-config.yml의 내용:

include:
  - local: /.gitlab-ci/config-defaults.yml

/.gitlab-ci/config-defaults.yml의 내용:

default:
  after_script:
    - echo "작업 완료."

중복된 includes 항목으로 중첩된 includes 사용

중첩된 includes는 동일한 구성 파일을 포함할 수 있습니다. 중복 구성 파일은 여러 번 포함되지만 한 번만 포함된 것과 동일한 효과를 나타냅니다.

예를들어, 다음 중첩된 includes를 사용하는 경우, defaults.gitlab-ci.yml가 여러 번 포함됩니다:

  • .gitlab-ci.yml 파일의 내용:

    include:
      - template: defaults.gitlab-ci.yml
      - local: unit-tests.gitlab-ci.yml
      - local: smoke-tests.gitlab-ci.yml
    
  • defaults.gitlab-ci.yml 파일의 내용:

    default:
      before_script: default-before-script.sh
      retry: 2
    
  • unit-tests.gitlab-ci.yml 파일의 내용:

    include:
      - template: defaults.gitlab-ci.yml
      
    unit-test-job:
      script: unit-test.sh
      retry: 0
    
  • smoke-tests.gitlab-ci.yml 파일의 내용:

    include:
      - template: defaults.gitlab-ci.yml
      
    smoke-test-job:
      script: smoke-test.sh
    

최종 구성은 다음과 같을 것입니다:

unit-test-job:
  before_script: default-before-script.sh
  script: unit-test.sh
  retry: 0

smoke-test-job:
  before_script: default-before-script.sh
  script: smoke-test.sh
  retry: 2

include와 함께 변수 사용

.gitlab-ci.yml 파일에서 include 섹션에서는 다음을 사용할 수 있습니다:

예를 들어:

include:
  project: '$CI_PROJECT_PATH'
  file: '.compliance-gitlab-ci.yml'

작업에서 정의된 변수나 모든 작업의 기본 변수를 정의하는 전역 variables 섹션에서 정의된 변수를 사용할 수 없습니다. Include는 작업보다 먼저 평가되므로 이러한 변수를 include와 함께 사용할 수 없습니다.

미리 정의된 변수를 include할 수 있는 방법과 변수가 CI/CD 작업에 미치는 영향에 대한 예제는 CI/CD variable demo를 참조하세요.

include와 함께 rules 사용

  • needs 작업 의존성을 지원하는 요청은 GitLab 15.11에서 소개되었습니다.

include와 함께 rules을 사용하여 조건에 따라 다른 구성 파일을 조건부로 포함할 수 있습니다.

rules를 다음과 같은 특정 변수 및 다음 키워드와 함께 사용할 수 있습니다:

rules:if와 함께 include

  • when: neverwhen:always를 지원하는 요청은 GitLab 16.1에 ci_support_include_rules_when_never라는 플래그로 도입되었습니다. 기본적으로 비활성화됩니다.
  • when: neverwhen:always의 지원이 GitLab 16.2에서 일반적으로 사용 가능하게 되었습니다. ci_support_include_rules_when_never 피처 플래그가 제거되었습니다.

rules:if를 사용하여 CI/CD 변수의 상태에 따라 다른 구성 파일을 조건부로 포함할 수 있습니다. 예를 들어:

include:
  - local: builds.yml
    rules:
      - if: $DONT_INCLUDE_BUILDS == "true"
        when: never
  - local: builds.yml
    rules:
      - if: $ALWAYS_INCLUDE_BUILDS == "true"
        when: always
  - local: builds.yml
    rules:
      - if: $INCLUDE_BUILDS == "true"
  - local: deploys.yml
    rules:
      - if: $CI_COMMIT_BRANCH == "main"

test:
  stage: test
  script: exit 0

rules:exists와 함께 include

  • when: neverwhen:always를 지원하는 요청은 GitLab 16.1에 ci_support_include_rules_when_never라는 플래그로 도입되었습니다. 기본적으로 비활성화됩니다.
  • when: neverwhen:always의 지원이 GitLab 16.2에서 일반적으로 사용 가능하게 되었습니다. ci_support_include_rules_when_never 피처 플래그가 제거되었습니다.

rules:exists를 사용하여 파일의 존재 여부에 따라 다른 구성 파일을 조건부로 포함할 수 있습니다. 예를 들어:

include:
  - local: builds.yml
    rules:
      - exists:
          - exception-file.md
        when: never
  - local: builds.yml
    rules:
      - exists:
          - important-file.md
        when: always
  - local: builds.yml
    rules:
      - exists:
          - file.md

test:
  stage: test
  script: exit 0

이 예에서, GitLab은 현재 프로젝트에 file.md의 존재여부를 확인합니다.

rules:existsinclude를 다른 프로젝트의 include 파일에서 설정하는 경우 알려진 문제가 있습니다. GitLab은 파일의 존재 여부를 다른 프로젝트에서 확인합니다. 예를 들어:

# my-group/my-project의 파이프라인 구성
include:
  - project: my-group/other-project
    ref: other_branch
    file: other-file.yml

test:
  script: exit 0

# my-group/other-project의 other-file.yml
include:
  - project: my-group/my-project
    ref: main
    file: my-file.yml
    rules:
      - exists:
          - file.md

위의 예시에서, GitLab은 커밋 ref other_branch에서 my-group/other-project에서의 file.md의 존재 여부를 확인하게 됩니다. include를 다른 프로젝트의 include 파일에 대해 검색하는 경우, 검색 문맥을 변경할 수 있도록 rules:exists:pathsrules:exists:project를 사용할 수 있습니다. 예를 들어:

include:
  - project: my-group/my-project
    ref: main
    file: my-file.yml
    rules:
      - exists:
          paths:
            - file.md
          project: my-group/my-project
          ref: main

rules:changes을 사용한 include

변경된 파일에 기반하여 다른 구성 파일을 조건부로 포함시키려면 rules:changes를 사용하십시오. 예를 들어:

include:
  - local: builds1.yml
    rules:
      - changes:
        - Dockerfile
  - local: builds2.yml
    rules:
      - changes:
          paths:
            - Dockerfile
          compare_to: 'refs/heads/branch1'
        when: always
  - local: builds3.yml
    rules:
      - if: $CI_PIPELINE_SOURCE == "merge_request_event"
        changes:
          paths:
            - Dockerfile

test:
  stage: test
  script: exit 0

이 예에서:

  • Dockerfile이 변경된 경우 builds1.yml이 포함됩니다.
  • Dockerfilerefs/heads/branch1에 대해 변경된 경우 builds2.yml이 포함됩니다.
  • Dockerfile이 변경되고 파이프라인 소스가 Merge Request 이벤트인 경우 builds3.yml이 포함됩니다.

와일드카드 파일 경로와 함께 include:local 사용하기

include:local과 와일드카드 경로(***)를 함께 사용할 수 있습니다.

예시:

include: 'configs/*.yml'

파이프라인이 실행될 때 GitLab은:

  • configs 디렉터리에 있는 모든 .yml 파일을 파이프라인 구성에 추가합니다.
  • configs 디렉터리의 하위 폴더에 있는 .yml 파일은 추가하지 않습니다. 이를 허용하려면, 다음 구성을 추가하세요:

    # `configs` 및 해당 하위 폴더에 있는 모든 `.yml` 파일과 일치합니다.
    include: 'configs/**.yml'
      
    # `configs` 하위 폴더에 있는 모든 `.yml` 파일과만 일치합니다.
    include: 'configs/**/*.yml'
    

문제 해결

Maximum of 150 nested includes are allowed! 오류

파이프라인의 중첩된 포함 파일 최대 개수는 150개입니다. 파이프라인에서 Maximum 150 includes are allowed 오류 메시지를 받으면, 아래 중 하나일 수 있습니다:

  • 일부 중첩된 구성이 과도하게 많은 추가 중첩된 include 구성을 포함하고 있습니다.
  • 중첩된 포함에서 우연히 루프가 발생했습니다. 예를 들어, include1.ymlinclude2.yml을 포함하고 include2.ymlinclude1.yml을 포함하여 반복적인 루프를 만들었습니다.

이러한 문제가 발생하는 것을 방지하기 위해 파이프라인 편집기를 사용하여 구성 파일을 편집하십시오. 해당 도구는 제한 값을 검증합니다. 루프 또는 과도한 포함된 파일이 문제의 원인인지를 좁혀보기 위해 한 번에 한 개의 포함된 파일을 제거할 수 있습니다.

GitLab 16.0부터 온프레미스 사용자는 최대 포함 값을 변경할 수 있습니다.

SSL_connect SYSCALL returned=5 errno=0 state=SSLv3/TLS write client hello 및 기타 네트워크 오류

include:remote를 사용할 때 GitLab은 원격 파일을 HTTP(S)를 통해 가져오려고 시도합니다. 다양한 연결 문제로 인해 이 프로세스가 실패할 수 있습니다.

SSL_connect SYSCALL returned=5 errno=0 state=SSLv3/TLS write client hello 오류는 GitLab이 원격 호스트에 HTTPS 연결을 설정하지 못하는 경우 발생합니다. 이 문제는 원격 호스트에 요청을 과도하게 하지 않도록 요청을 제한하는 속도 제한이 있는 경우에 발생할 수 있습니다.

예를 들어, GitLab.com의 GitLab Pages 서버가 속도 제한을 가지고 있습니다. GitLab Pages 사이트에서 호스팅되는 CI/CD 구성 파일을 반복해서 가져오려고하면 속도 제한에 도달하여 오류가 발생할 수 있습니다. GitLab Pages 사이트에 CI/CD 구성 파일을 호스팅하지 않도록하십시오.

가능하면 외부 HTTP(S) 요청없이 GitLab 인스턴스 내의 다른 프로젝트에서 구성 파일을 가져오기 위해 include:project를 사용하십시오.