다른 파일의 CI/CD 설정 사용하기
다른 파일의 CI/CD 설정 사용하기
include로 외부 YAML 파일을 CI/CD 작업에 포함하는 방법을 설명하는 문서예요. 설정 파일을 여러 곳에서 재사용해 중복을 줄이고 유지보수를 쉽게 만드는 것이 핵심이에요.
단일·배열 포함, default 사용, 설정 값 재정의(오버라이드), 병합 규칙, 중첩 include, rules와의 조합까지 폭넓게 옆에서 설명해 주는 방식으로 정리했어요.
출처: 문서
본문
include를 사용해 외부 YAML 파일을 CI/CD 작업에 포함할 수 있어요.
단일 설정 파일 포함하기
단일 설정 파일을 포함하려면 include에 단일 파일을 다음 두 문법 중 하나로 사용하세요.
- 같은 줄에:
include: 'my-config.yml' - 배열의 단일 항목으로:
include: - 'my-config.yml'
파일이 로컬 파일이면 include:local과 동일하게 동작해요. 파일이 원격 파일이면 include:remote와 동일해요.
설정 파일 배열 포함하기
설정 파일의 배열을 포함할 수 있어요.
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 명령은 두 rspec 작업 모두에서 script 명령보다 먼저 실행돼요.
포함된 설정 값 재정의하기
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_USER와 POSTGRES_PASSWORD 변수와 production 작업의 environment:url이 autodevops-template.yml 파일에 정의된 값을 재정의해요. 다른 키워드는 변경되지 않아요. 이 방법을 *병합(merging)*이라고 해요.
include의 병합 방법
include 구성은 다음 과정으로 메인 설정 파일과 병합돼요.
- 포함된 파일은 설정 파일에 정의된 순서대로 읽히고, 포함된 구성도 같은 순서로 병합돼요.
- 포함된 파일이
include를 사용하면 그 중첩include구성이 먼저 (재귀적으로) 병합돼요. - 매개변수가 겹치면 포함된 파일의 구성을 병합할 때 마지막으로 포함된 파일이 우선해요.
include로 추가된 모든 구성이 병합된 후, 메인 구성이 포함된 구성과 병합돼요.
이 병합 방법은 *딥 병합(deep merge)*으로, 해시 맵이 구성의 어느 깊이에서든 병합돼요. 지금까지 병합된 구성을 포함하는 해시 맵 "A"와 (다음 구성 조각) "B"를 병합할 때 키와 값은 다음과 같이 처리돼요.
- 키가 A에만 있으면 A의 키와 값을 사용.
- 키가 A와 B 모두에 있고 둘 다 해시 맵이면 그 해시 맵들을 병합.
- 키가 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
이 예시에서:
- 변수는 모든 파일이 병합된 후에만 평가돼요. 포함된 파일의 작업이 다른 파일에 정의된 변수 값을 사용할 수도 있어요. 병합 후 CI/CD 변수 우선순위가 각 변수의 최종 값을 결정해요.
rules는 배열이라 병합할 수 없어요. 최상위 파일이 우선해요.artifacts는 해시 맵이라 딥 병합될 수 있어요.
포함된 구성 배열 재정의하기
병합을 사용해 포함된 템플릿의 구성을 확장하고 재정의할 수 있지만, 배열의 개별 항목을 추가하거나 수정할 수는 없어요. 예를 들어 확장된 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_dependencies와 deploy를 반복하지 않으면 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 "Job complete."
중복 include 항목으로 중첩 include 사용하기
메인 설정 파일과 중첩 include에서 같은 설정 파일을 여러 번 포함할 수 있어요.
어떤 파일이 재정의(overrides)로 포함된 구성을 변경한다면 include 항목의 순서가 최종 구성에 영향을 줄 수 있어요. 구성이 마지막으로 포함된 시점이 이전에 포함된 시점을 재정의해요. 예를 들어:
defaults.gitlab-ci.yml 파일의 내용:
default:
before_script: echo "Default before script"
unit-tests.gitlab-ci.yml 파일의 내용:
include:
- template: defaults.gitlab-ci.yml
default: # Override the included default
before_script: echo "Unit test default override"
unit-test-job:
script: unit-test.sh
smoke-tests.gitlab-ci.yml 파일의 내용:
include:
- template: defaults.gitlab-ci.yml
default: # Override the included default
before_script: echo "Smoke test default override"
smoke-test-job:
script: smoke-test.sh
이 세 파일로, 포함되는 순서가 최종 구성을 바꿔요.
unit-tests가 먼저 포함된 경우 .gitlab-ci.yml 파일의 내용:
include:
- local: unit-tests.gitlab-ci.yml
- local: smoke-tests.gitlab-ci.yml
최종 구성은 다음과 같아요.
unit-test-job:
before_script: echo "Smoke test default override"
script: unit-test.sh
smoke-test-job:
before_script: echo "Smoke test default override"
script: smoke-test.sh
unit-tests가 마지막에 포함된 경우 .gitlab-ci.yml 파일의 내용:
include:
- local: smoke-tests.gitlab-ci.yml
- local: unit-tests.gitlab-ci.yml
최종 구성은 다음과 같아요.
unit-test-job:
before_script: echo "Unit test default override"
script: unit-test.sh
smoke-test-job:
before_script: echo "Unit test default override"
script: smoke-test.sh
어떤 파일도 포함된 구성을 재정의하지 않으면 include 항목의 순서는 최종 구성에 영향을 주지 않아요.
include와 함께 변수 사용하기
.gitlab-ci.yml 파일의 include 섹션에서 다음을 사용할 수 있어요.
- 프로젝트 변수.
- 그룹 변수.
- 인스턴스 변수.
- 프로젝트 사전 정의 변수 (
CI_PROJECT_*). - 트리거 변수.
- 예약 파이프라인 변수.
- 수동 파이프라인 실행 변수.
CI_PIPELINE_SOURCE및CI_PIPELINE_TRIGGERED사전 정의 변수.$CI_COMMIT_REF_NAME사전 정의 변수.
예를 들어:
include:
project: '$CI_PROJECT_PATH'
file: '.compliance-gitlab-ci.yml'
작업에서 정의된 변수나 모든 작업의 기본 변수를 정의하는 전역 variables 섹션의 변수는 사용할 수 없어요. Include는 작업보다 먼저 평가되므로 이 변수들은 include와 함께 사용할 수 없어요.
사전 정의 변수를 포함하는 방법과 변수가 CI/CD 작업에 미치는 영향의 예시는 이 CI/CD 변수 데모를 참고하세요.
동적 하위 파이프라인의 구성에는 include 섹션에서 CI/CD 변수를 사용할 수 없어요. 이 문제는 이슈 378717에서 수정을 제안하고 있어요.
include와 함께 rules 사용하기
rules를 include와 함께 사용해 다른 설정 파일을 조건부로 포함할 수 있어요.
rules는 특정 변수와 다음 키워드에서만 사용할 수 있어요.
rules:if와 함께 include 사용
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 사용
이력
regexp:지원은 GitLab 19.2에서 도입.
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의 존재를 확인해요.
다른 프로젝트의 include 파일에서 rules:exists와 함께 include를 사용한다면 구성을 주의 깊게 검토하세요. GitLab은 파일 존재를 다른 프로젝트에서 확인해요. 예를 들어:
# Pipeline configuration in my-group/my-project
include:
- project: my-group/other-project
ref: other_branch
file: other-file.yml
test:
script: exit 0
# other-file.yml in my-group/other-project on ref other_branch
include:
- project: my-group/my-project
ref: main
file: my-file.yml
rules:
- exists:
- file.md
이 예시에서 GitLab은 file.md의 존재를 파이프라인이 실행되는 프로젝트/ref가 아니라 my-group/other-project의 커밋 ref other_branch에서 검색해요.
검색 컨텍스트를 변경하려면 rules:exists:paths와 함께 rules: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 사용
이력
regexp:지원은 GitLab 19.2에서 도입.
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이 포함돼요.Dockerfile이refs/heads/branch1에 상대적으로 변경되면builds2.yml이 포함돼요.Dockerfile이 변경되고 파이프라인 소스가 머지 리퀘스트 이벤트이면builds3.yml이 포함돼요.builds3.yml의 작업들도 머지 리퀘스트 파이프라인에서 실행되도록 구성해야 해요.
와일드카드 파일 경로와 함께 include:local 사용하기
include:local에서 와일드카드 경로(* 및 **)를 사용할 수 있어요.
예시:
include: 'configs/*.yml'
파이프라인이 실행될 때 GitLab은:
configs디렉터리의 모든.yml파일을 파이프라인 구성에 추가해요.configs디렉터리의 하위 폴더에 있는.yml파일은 추가하지 않아요. 이를 허용하려면 다음 구성을 추가하세요.# This matches all `.yml` files in `configs` and any subfolder in it. include: 'configs/**.yml' # This matches all `.yml` files only in subfolders of `configs`. include: 'configs/**/*.yml'
문제 해결
Maximum of 150 nested includes are allowed! 오류
파이프라인의 중첩 포함 파일 최대 개수는 150개예요. 파이프라인에서 Maximum 150 includes are allowed 오류 메시지를 받으면 다음 중 하나일 가능성이 높아요.
- 포함된 중첩 구성 중 일부가 비정상적으로 많은 수의 추가 중첩
include구성을 포함함. - 중첩 include에 우발적 순환이 있음. 예를 들어
include1.yml이include2.yml을 포함하고include2.yml이include1.yml을 포함해 재귀 루프를 만드는 경우.
이런 위험을 줄이려면 제한에 도달했는지 검증하는 파이프라인 편집기로 파이프라인 설정 파일을 편집하세요. 한 번에 하나씩 포함 파일을 제거해 순환이나 과도한 포함 파일의 원인이 되는 설정 파일을 좁혀 나갈 수 있어요.
GitLab Self-Managed 사용자는 최대 include 수 값을 변경할 수 있어요.
오류: include:local에서 Local file <file> does not exist!
include:local을 사용할 때 파일이 저장소에 존재함에도 Local file <file> does not exist! 오류를 받을 수 있어요.
이 오류는 CI/CD 구성 문제가 아닌 알려진 시스템 수준 이슈예요. 분산 Gitaly 또는 Praefect 설정에서 간헐적으로 관찰돼요. 이 오류가 발생하면 파이프라인을 다시 시도하세요.
자세한 내용은 이슈 336789을 참고하세요.
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 연결을 설정할 수 없을 때 발생해요. 원격 호스트가 요청으로 서버에 과부하가 걸리는 것을 방지하는 속도 제한(rate limit)이 있는 경우 이 문제가 발생할 수 있어요.
예를 들어 GitLab.com의 GitLab Pages 서버는 속도 제한이 있어요. GitLab Pages에 호스팅된 CI/CD 구성 파일을 반복적으로 가져오려 하면 속도 제한에 도달해 오류가 발생할 수 있어요. CI/CD 구성 파일을 GitLab Pages 사이트에 호스팅하는 것은 피해야 해요.
가능하면 include:project를 사용해 외부 HTTP(S) 요청 없이 GitLab 인스턴스의 다른 프로젝트에서 구성 파일을 가져오세요.
더 알아보기
include가 제공하는 각 유형(local, remote, template, project)의 세부 문법은 CI/CD YAML 문법 참조에서 확인할 수 있어요. default·rules 키워드와 함께 조합해 구성의 재사용성을 높이는 방법도 함께 익히면 좋아요.