GitLab CI/CD 템플릿 개발 가이드 (지원 종료)
GitLab v19.4요약
CI/CD 카탈로그가 도입되면서, GitLab은 코드베이스에 새 CI/CD 템플릿 기여를 받지 않습니다. 이 문서에서는 GitLab CI/CD 템플릿을 개발하는 방법을 설명합니다. 새 CI/CD 템플릿이나 업데이트한 CI/CD 템플릿으로 머지 리퀘스트를 제출하기 전에 다음을 수행해야 합니다.
CI/CD 카탈로그가 도입되면서, GitLab은 코드베이스에 새 CI/CD 템플릿 기여를 받지 않습니다. 대신 팀원이 카탈로그용 CI/CD 컴포넌트를 만들 것을 권장합니다. 이 전환은 공유 CI/CD 리소스의 모듈성과 유지 관리성을 높이고, 새 CI/CD 템플릿을 기여할 때 따르는 복잡성을 피합니다. 기존 템플릿을 업데이트해야 한다면, 대응하는 CI/CD 컴포넌트도 함께 업데이트해야 합니다. CI/CD 템플릿에 대응하는 컴포넌트가 아직 없다면, 대응 컴포넌트 생성을 고려합니다. 이렇게 하면 템플릿과 컴포넌트의 기능이 계속 동기화되고, 새 개발 관행에도 부합합니다.
이 문서에서는 GitLab CI/CD 템플릿을 개발하는 방법을 설명합니다.
CI/CD 템플릿 요구 사항#
새 CI/CD 템플릿이나 업데이트한 CI/CD 템플릿으로 머지 리퀘스트를 제출하기 전에 다음을 수행해야 합니다.
- 템플릿을 올바른 디렉터리에 배치합니다.
- CI/CD 템플릿 작성 가이드라인을 따릅니다.
- 템플릿 이름을
*.gitlab-ci.yml형식으로 지정합니다. - 유효한
.gitlab-ci.yml구문을 사용합니다. CI/CD lint 도구로 유효한지 검증합니다. - 템플릿 메트릭을 추가합니다.
- 머지 리퀘스트가 사용자에게 보이는 변경을 도입한다면 변경 로그를 포함합니다.
- 템플릿 검토 프로세스를 따릅니다.
- (선택 사항이지만 강력히 권장) 검토자가 접근할 수 있는 예시 GitLab 프로젝트에서 템플릿을 테스트합니다. 검토자는 템플릿에 필요한 데이터나 구성을 만들 수 없을 수 있으므로, 예시 프로젝트가 있으면 검토자가 템플릿이 올바른지 확인하는 데 도움이 됩니다. 머지 리퀘스트를 검토용으로 제출하기 전에 예시 프로젝트의 파이프라인이 성공해야 합니다.
템플릿 디렉터리#
모든 템플릿 파일은 lib/gitlab/ci/templates에 저장됩니다. 일반 템플릿은 이
디렉터리에 저장하지만, 특정 템플릿 유형에는 전용 디렉터리가 예약돼 있습니다.
새 파일 UI에서 템플릿을 선택할 수
있는지는 템플릿이 들어 있는 디렉터리에 따라 결정됩니다.
| 하위 디렉터리 | UI에서 선택 가능 | 템플릿 유형 |
|---|---|---|
/* (루트) |
예 | 일반 템플릿. |
/AWS/* |
아니요 | 클라우드 배포(AWS) 관련 템플릿. |
/Jobs/* |
아니요 | Auto DevOps 관련 템플릿. |
/Pages/* |
예 | GitLab Pages에서 정적 사이트 생성기를 사용하는 샘플 템플릿. |
/Security/* |
예 | 보안 스캐너 관련 템플릿. |
/Terraform/* |
아니요 | 코드형 인프라(Terraform) 관련 템플릿. |
/Verify/* |
예 | 테스트 기능 관련 템플릿. |
/Workflows/* |
아니요 | workflow: 키워드를 사용하는 샘플 템플릿. |
템플릿 작성 가이드라인#
다음 가이드라인에 따라 제출하는 템플릿이 표준을 따르는지 확인합니다.
템플릿 유형#
템플릿에는 작성 방식과 사용 방식에 영향을 주는 두 가지 유형이 있습니다. 템플릿의 스타일은 이 두 유형 중 하나와 일치해야 합니다.
파이프라인 템플릿은 프로젝트의 구조나 언어 등에 맞는 엔드투엔드 CI/CD
워크플로를 제공합니다. 보통 다른 .gitlab-ci.yml 파일이 없는 프로젝트에서
단독으로 사용합니다.
파이프라인 템플릿을 작성할 때는 다음을 따릅니다.
image나before_script같은 전역 키워드는 템플릿 상단의default섹션에 배치합니다.- 템플릿을 기존
.gitlab-ci.yml파일에서includes키워드와 함께 사용하도록 설계했는지 여부를 코드 주석에 명확히 기재합니다.
job 템플릿은 특정 작업을 수행하기 위해 기존 CI/CD 워크플로에 추가할 수 있는
특정 job을 제공합니다. 보통 includes
키워드로 기존 .gitlab-ci.yml 파일에 추가해 사용합니다. 내용을 기존
.gitlab-ci.yml 파일에 복사해 붙여 넣을 수도 있습니다.
사용자가 현재 파이프라인에 수정 없이 또는 아주 적은 수정으로 추가할 수 있도록 job 템플릿을 구성합니다. 다른 파이프라인 구성과 충돌할 위험을 줄이도록 구성해야 합니다.
job 템플릿을 작성할 때는 다음을 따릅니다.
- 전역 또는
default키워드를 사용하지 않습니다. 루트.gitlab-ci.yml이 템플릿을 포함하면 전역 또는 default 키워드가 재정의되어 예상치 못한 동작이 발생할 수 있습니다. job 템플릿에 특정 Stage가 필요하다면, 사용자가 메인.gitlab-ci.yml구성에 그 Stage를 직접 추가해야 한다고 코드 주석에 설명합니다. - 템플릿을
includes키워드와 함께 사용하도록 설계했는지, 아니면 기존 구성에 복사해 넣도록 설계했는지 코드 주석에 명확히 기재합니다. - 하위 호환성 문제를 피하기 위해 최신 버전과 안정 버전으로
템플릿의 버전 관리를 고려합니다.
이 유형의 템플릿은 유지 관리가 더 복잡합니다.
includes로 가져온 템플릿을 변경하면 그 템플릿을 사용하는 모든 프로젝트의 파이프라인이 깨질 수 있기 때문입니다.
템플릿을 작성할 때 추가로 유념할 사항입니다.
| 템플릿 설계 고려 사항 | 파이프라인 템플릿 | job 템플릿 |
|---|---|---|
stages를 포함한 전역 키워드를 사용할 수 있습니다. |
예 | 아니요 |
| job을 정의할 수 있습니다. | 예 | 예 |
| 새 파일 UI에서 선택할 수 있습니다 | 예 | 아니요 |
include로 다른 job 템플릿을 포함할 수 있습니다 |
예 | 아니요 |
include로 다른 파이프라인 템플릿을 포함할 수 있습니다. |
아니요 | 아니요 |
구문 가이드라인#
템플릿을 이해하기 쉽게 하려면, 모든 템플릿이 일관된 형식으로 명확한 구문 스타일을 사용해야 합니다.
모든 job의 before_script, script, after_script 키워드는
ShellCheck로 린트되며, 가능한 한
셸 스크립팅 표준 및 스타일 가이드라인을
따라야 합니다.
ShellCheck은 스크립트가 Bash로 실행되도록 설계됐다고 가정합니다.
Bash ShellCheck 규칙과 호환되지 않는 셸용 스크립트를 사용하는 템플릿은 ShellCheck 린트에서
제외할 수 있습니다. 스크립트를 제외하려면 scripts/lint_templates_bash.rb의
EXCLUDED_TEMPLATES 목록에 추가합니다.
기본 브랜치 하드코딩 금지#
하드코딩한 main 브랜치 대신 $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH를
사용하고, master는 절대 사용하지 않습니다.
job:
rules:
if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
echo "example job"
only 나 except 대신 rules 사용#
가능하면 only 또는 except 사용을 피합니다.
only와 except는 더 이상 개발되지 않으며, 이제 rules가
권장 구문입니다.
job2:
script:
- echo
rules:
- if: $CI_COMMIT_BRANCH
긴 명령 분할#
명령이 매우 길거나 -o 또는 --option 같은 커맨드라인 플래그가 많다면 다음과 같이 합니다.
- 명령의 모든 부분을 쉽게 볼 수 있도록 여러 줄 명령으로 분할합니다.
- 사용할 수 있다면 플래그의 긴 이름을 사용합니다.
예를 들어 docker run --e SOURCE_CODE="$PWD" -v "$PWD":/code -v /var/run/docker.sock:/var/run/docker.sock "$CODE_QUALITY_IMAGE" /code
처럼 짧은 CLI 플래그를 사용한 긴 명령은 다음과 같이 작성합니다.
job1:
script:
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"$CODE_QUALITY_IMAGE" /code
|와 > YAML 연산자로 여러 줄 명령을 분할할 수도 있습니다.
주석으로 템플릿 설명#
새 파일 메뉴에서 템플릿 내용을 확인할 수 있고, 사용자가 템플릿 정보를 보는 곳이 여기뿐일 수도 있습니다. 템플릿의 동작을 템플릿 자체에 직접 명확히 문서화하는 것이 중요합니다.
다음 가이드라인은 모든 템플릿 제출에 기대되는 기본 주석을 다룹니다. 주석이 사용자나 템플릿 검토자에게 도움이 된다고 판단되면 필요에 따라 주석을 더 추가합니다.
요구 사항과 기대 동작 설명#
파일 상단의 # 주석으로 템플릿 사용 방법을 자세히 설명합니다. 여기에는 다음이
포함됩니다.
- 리포지터리/프로젝트 요구 사항.
- 기대 동작.
- 템플릿을 사용하기 전에 사용자가 편집해야 하는 부분.
- 템플릿을 구성 파일에 복사해 붙여 넣어야 하는지, 아니면 기존 파이프라인에서
include키워드로 사용해야 하는지 여부. - 프로젝트의 CI/CD 설정에 저장해야 하는 변수가 있는지 여부.
# Use this template to publish an application that uses the ABC server.
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
#
# Requirements:
# - An ABC project with content saved in /content and tests in /test
# - A CI/CD variable named ABC-PASSWORD saved in the project CI/CD settings. The value
# should be the password used to deploy to your ABC server.
# - An ABC server configured to listen on port 12345.
#
# You must change the URL on line 123 to point to your ABC server and port.
#
# For more information, see https://gitlab.com/example/abcserver/README.md
job1:
...
변수가 템플릿 동작에 미치는 영향 설명#
템플릿이 변수를 사용한다면, 변수가 처음 정의되는 위치의 # 주석으로 설명합니다. 변수의
의미가 자명하면 주석을 생략할 수 있습니다.
variables: # Good to have a comment here, for example:
TEST_CODE_PATH: <path/to/code> # Update this variable with the relative path to your Ruby specs
job1:
variables:
ERROR_MESSAGE: "The $TEST_CODE_PATH path is invalid" # (No need for a comment here, it's already clear)
script:
- echo ${ERROR_MESSAGE}
로컬이 아닌 변수에 모두 대문자 이름 사용#
CI/CD 설정이나 variables 키워드로 변수가 제공될 것으로 기대한다면, 그 변수는 단어를
밑줄(_)로 구분하고 모두 대문자로 이름을 지정해야
합니다.
.with_login:
before_script:
# SECRET_TOKEN should be provided via the project settings
- echo "$SECRET_TOKEN" | docker login -u my-user --password-stdin my-registry
script 키워드 중 하나에서 로컬로 정의되는 변수에는 소문자 이름을 선택적으로 사용할 수
있습니다.
job1:
script:
- response="$(curl "https://example.com/json")"
- message="$(echo "$response" | jq -r .message)"
- 'echo "Server responded with: $message"'
하위 호환성#
템플릿은 include:template: 키워드로 동적으로 포함될 수 있습니다. 기존 템플릿을
변경한다면, 그 변경이 기존 프로젝트의 CI/CD를 깨뜨리지 않는지 반드시 확인해야
합니다.
예를 들어 템플릿의 job 이름을 변경하면 기존 프로젝트의 파이프라인이 깨질 수 있습니다.
이 예시에서 Performance.gitlab-ci.yml이라는 템플릿의 내용은 다음과 같습니다.
performance:
image: registry.gitlab.com/gitlab-org/verify-tools/performance:v0.1.0
script: ./performance-test $TARGET_URL
그리고 사용자는 performance job에 인수를 전달하면서 이 템플릿을 포함합니다. 사용자의
.gitlab-ci.yml에 CI/CD 변수 TARGET_URL을 지정하면 이렇게 할 수 있습니다.
include:
template: Performance.gitlab-ci.yml
performance:
variables:
TARGET_URL: https://awesome-app.com
템플릿의 job 이름 performance를 browser-performance로 변경하면, 포함된 템플릿에
performance라는 이름의 job 이 더 이상 없으므로 사용자의 .gitlab-ci.yml에서 즉시
린트 오류가 발생합니다. 따라서 사용자는 자신의 .gitlab-ci.yml을 수정해야 하고, 이는
사용자의 워크플로를 방해할 수 있습니다.
호환성을 깨는 변경을 안전하게 도입하는 방법은 버전 관리 섹션을 참고합니다.
버전 관리#
현재 템플릿에 의존하는 기존 프로젝트에 영향을 주지 않고 호환성을 깨는 변경을 도입하려면, 안정 버전과 최신 버전 관리를 사용합니다.
안정 템플릿은 보통 메이저 버전 릴리스에서만 호환성을 깨는 변경을 받는 반면, 최신 템플릿은 어떤 릴리스에서든 호환성을 깨는 변경을 받을 수 있습니다. 메이저 릴리스 마일스톤에서는 최신 템플릿이 새 안정 템플릿이 되며, 최신 템플릿은 삭제될 수 있습니다.
최신 템플릿을 추가하는 것은 안전하지만 유지 관리 부담이 따릅니다.
- GitLab은 다음 GitLab 메이저 릴리스에서 안정 템플릿을 최신 템플릿의 내용으로 덮어쓸 DRI를 지정해야 합니다. DRI는 그 변경으로 문제를 겪는 사용자를 지원할 책임이 있습니다.
- 호환성을 깨지 않는 새 변경을 적용할 때는 안정 템플릿과 최신 템플릿을 가능한 한 같게 유지하도록 둘 다 업데이트해야 합니다.
- 많은 사용자가 최신 템플릿이 계속 존재한다는 점에 직접 의존할 수 있으므로, 최신 템플릿이 계획보다 오래 남을 수 있습니다.
새 최신 템플릿을 추가하기 전에, 호환성을 깨는 변경이라도 안정 템플릿에 대신 적용할 수 있는지 확인합니다. 템플릿이 복사해 붙여 넣는 용도로만 쓰인다면 안정 버전을 직접 변경할 수 있습니다. 마이너 마일스톤에서 호환성을 깨는 변경으로 안정 템플릿을 변경하기 전에 다음을 확인합니다.
- 파이프라인 템플릿이고,
includes와 함께 사용하도록 설계되지 않았음을 설명하는 코드 주석이 있습니다. - CI/CD 템플릿 사용 메트릭에 사용량이 나타나지 않습니다. 메트릭에서 해당
템플릿의 사용량이 0 이면, 그 템플릿은
include로 활발히 사용되지 않는 것입니다.
안정 버전#
안정 CI/CD 템플릿은 메이저 릴리스 마일스톤에서만 호환성을 깨는 변경을 도입하는
템플릿입니다. 템플릿의 안정 버전 이름은 <template-name>.gitlab-ci.yml로 지정합니다.
예를 들어 Jobs/Deploy.gitlab-ci.yml 입니다.
15.0 같은 GitLab 메이저 마일스톤 릴리스에서 사용할 수 있는 최신 템플릿을
복사해 새 안정 템플릿을 만들 수 있습니다. 호환성을 깨는 모든 변경은
버전별 지원 중단 및 제거 페이지에 공지해야 합니다.
다음 조건을 충족하면 15.1 같은 GitLab 마이너 릴리스에서 안정 템플릿 버전을 변경할 수 있습니다.
- 그 변경이 호환성을 깨는 변경이 아닙니다.
- 최신 템플릿이 있다면 그 변경이 최신 템플릿에도 반영됩니다.
최신 버전#
latest로 표시된 템플릿은 호환성을 깨는 변경이 있더라도
어떤 릴리스에서든 업데이트될 수 있습니다. 최신 버전으로 간주되는 템플릿은 이름에
.latest를 추가합니다. 예를 들어 Jobs/Deploy.latest.gitlab-ci.yml 입니다.
호환성을 깨는 변경을 도입할 때는 업그레이드 경로를 테스트하고 문서화해야 합니다. 일반적으로 최신 템플릿은 예상치 못한 문제로 사용자를 놀라게 할 수 있으므로, 최선의 선택지로 홍보해서는 안 됩니다.
latest 템플릿이 아직 없다면 안정 템플릿을 복사할 수 있습니다.
이전 안정 템플릿을 포함하는 방법#
사용자는 현재 GitLab 패키지에 번들로 포함되지 않은 이전 안정 템플릿을 사용하고 싶을 수 있습니다. 예를 들어 GitLab 18.0과 GitLab 19.0의 안정 템플릿이 너무 달라서, GitLab 19.0으로 업그레이드한 뒤에도 GitLab 18.0 템플릿을 계속 사용하고 싶을 수 있습니다.
include:remote로 이전 템플릿 버전을 포함하는 방법을 템플릿이나 문서에 메모로 추가할 수
있습니다. 다른 템플릿을 include: template으로 포함한다면, include: remote와 함께
사용할 수 있습니다.
# To use the v13 stable template, which is not included in v14, fetch the specific
# template from the remote template repository with the `include:remote:` keyword.
# If you fetch from the GitLab canonical project, use the following URL format:
# https://gitlab.com/gitlab-org/gitlab/-/raw/<version>/lib/gitlab/ci/templates/<template-name>
include:
- template: Auto-DevOps.gitlab-ci.yml
- remote: https://gitlab.com/gitlab-org/gitlab/-/raw/v13.0.1-ee/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
추가 자료#
GitLab CI/CD 템플릿에 버전 관리 개념을 도입하는 것에 관한 공개 이슈가 있습니다. 그 이슈에서 진행 상황을 확인할 수 있습니다.
테스트#
각 CI/CD 템플릿은 게시해도 안전한지 확인하기 위해 테스트해야 합니다.
수동 QA#
템플릿을 최소한의 데모 프로젝트에서 테스트하는 것은 항상 좋은 관행입니다. 그러려면 다음 단계를 따릅니다.
- https://gitlab.com에 공개 샘플 프로젝트를 만듭니다.
- 제안한 템플릿을 담은
.gitlab-ci.yml을 프로젝트에 추가합니다. - 파이프라인을 실행하고, 가능한 모든 경우(머지 리퀘스트 파이프라인, 스케줄 등)에서 모든 것이 제대로 실행되는지 확인합니다.
- 새 템플릿을 추가하는 머지 리퀘스트의 설명에 해당 프로젝트를 링크합니다.
이는 검토자가 템플릿을 머지해도 안전한지 확인하는 데 유용한 정보입니다.
새 템플릿을 UI에서 선택할 수 있는지 확인#
일부 디렉터리에 있는 템플릿은 New file UI에서도 선택할 수 있습니다. 그런 디렉터리 중 하나에 템플릿을 추가할 때는, 드롭다운 목록에 올바르게 나타나는지 확인합니다.

RSpec 테스트 작성#
파이프라인 job 이 올바르게 생성되는지 확인하는 RSpec 테스트를 작성해야 합니다.
spec/lib/gitlab/ci/templates/<template-category>/<template-name>_spec.rb에 테스트 파일을 추가합니다.Ci::CreatePipelineService를 통해 파이프라인 job 이 제대로 생성되는지 테스트합니다.
호환성을 깨는 변경 검증#
latest 템플릿에 호환성을 깨는 변경을 도입할 때는 다음을
수행해야 합니다.
- 안정 템플릿에서의 업그레이드 경로를 테스트합니다.
- 사용자가 어떤 종류의 오류를 겪는지 확인합니다.
- 문제 해결 가이드로 문서화합니다.
이 정보는 안정 템플릿이 GitLab 메이저 버전 릴리스에서 업데이트될 때 사용자에게 중요합니다.
메트릭 추가#
모든 CI/CD 템플릿에는 사용량을 추적할 메트릭도 정의해야 합니다. CI/CD 템플릿 월간 사용 보고서는 Sisense(GitLab 팀원 전용)에서 확인할 수 있습니다. 템플릿을 선택하면 해당 템플릿 하나의 그래프를 볼 수 있습니다.
새 템플릿의 메트릭 정의를 추가하려면 다음과 같이 합니다.
-
GitLab GDK를 설치하고 시작합니다.
-
GDK의
gitlab디렉터리에서 새 템플릿이 들어 있는 브랜치를 체크아웃합니다. -
주간 및 월간 CI/CD 템플릿 총계 메트릭에 새 템플릿 이벤트 이름을 추가합니다.
-
새 메트릭 정의를 추가하려면 위와 같은 이벤트 이름을 다음 명령의 마지막 인수로 사용합니다.
bundle exec rails generate gitlab:usage_metric_definition:redis_hll ci_templates <template_metric_event_name>출력은 다음과 같습니다.
$ bundle exec rails generate gitlab:usage_metric_definition:redis_hll ci_templates p_ci_templates_my_template_name create config/metrics/counts_7d/20220120073740_p_ci_templates_my_template_name_weekly.yml create config/metrics/counts_28d/20220120073746_p_ci_templates_my_template_name_monthly.yml -
새로 생성된 두 파일을 다음과 같이 편집합니다.
-
name:과performance_indicator_type:: 삭제합니다(필요하지 않습니다). -
introduced_by_url:: 템플릿을 추가하는 MR의 URL 입니다. -
data_source::redis_hll로 설정합니다. -
description: 이 메트릭이 무엇을 세는지 간단한 설명을 추가합니다. 예:Count of pipelines using the latest Auto Deploy template -
product_*: 메트릭 딕셔너리 가이드에 따라 섹션, Stage, 그룹, 기능 카테고리로 설정합니다. 이 키워드에 무엇을 사용할지 확실하지 않으면 머지 리퀘스트에서 도움을 요청할 수 있습니다. -
각 파일 끝에 다음을 추가합니다.
options: events: - p_ci_templates_my_template_name
-
-
변경 사항을 커밋하고 푸시합니다.
예를 들어 다음은 5 Minute Production App 템플릿의 메트릭 구성 파일입니다.
- 주간 및 월간 메트릭 정의입니다.
- 메트릭 총계입니다.
보안#
템플릿에는 악성 코드가 들어 있을 수 있습니다. 예를 들어 job에 export 셸 명령이 들어 있는 템플릿은
job 로그에 시크릿 프로젝트 CI/CD 변수를 실수로 노출할 수 있습니다.
안전한지 확실하지 않으면 보안 전문가에게 교차 검증을 요청해야 합니다.
CI/CD 템플릿 머지 리퀘스트 기여#
CI/CD 템플릿 MR을 만들고 ci::templates 레이블을 지정하면, DangerBot 이 코드를 검토할 수
있는 검토자 한 명과 메인테이너 한 명을 제안합니다. 머지 리퀘스트가 검토받을 준비가 되면
검토자를 멘션하고 CI/CD 템플릿 변경을 검토해
달라고 요청합니다. 자세한 내용은 CI/CD 템플릿 MR 용 DangerBot 작업을 추가한 머지 리퀘스트에서
확인할 수 있습니다.