GitLab CI/CD 実践[応用編]:共通設定と外部ファイルの利用

はじめに

前回の記事では、2回にわたりGitLab CI/CDの基本的なパイプライン作成方法 を解説しました。ジョブの定義からステージの構成まで、一通りの流れを実際に試しながら理解できたと思います。

しかし、実際にチーム開発を進めていくと、パイプラインの定義ファイルである.gitlab-ci.ymlがすぐに肥大化しがちです。

  • 同じ処理を複数のジョブに書いてしまう
  • プロジェクトごとに似たような CI 定義をコピペして使い回す

こうした状態になると、修正や共通化が難しくなり、運用コストが増えてしまいます。

そこで今回の記事では、GitLab CI/CDが用意しているincludeextendsの仕組みに注目します。これらを活用することで、設定を整理し、再利用しやすい形に整えることができます。
小さな検証を通して、それぞれの機能がどのように役立つかを紹介していきます。

include機能:外部ファイルのインポート

includeは、別ファイルに書かれたCI定義を取り込む機能です。別のプロジェクトにあるファイルを読み込めるのが大きな特徴です。今回の検証では、テスト用にGitLab上で 2 つのプロジェクトを用意し、一方のプロジェクトにあるパイプライン定義を、もう一方のプロジェクトからincludeで読み込む形を確認しました。

検証環境

  • メインプロジェクト:runner-test-project-1
    • .gitlab-ci.yml(実際にパイプラインを実行する定義ファイル)
  • インポート用プロジェクト:runner-test-project-2
    • ci/shared.yml(他のプロジェクトから取り込んで使うためのジョブ定義ファイル)

設定例(実行側)

# runner-test-project-1/.gitlab-ci.yml

variables:
  FROM_PROJECT: "overridden-in-runner-test-project-1"

include:
  - project: "group/runner-test-project-2"
    ref: "main"
    file: "/ci/shared.yml"

stages: [test]

check-local:
  stage: test
  script:
    - echo "FROM_PROJECT=${FROM_PROJECT}"

設定例(includeされる側)

# runner-test-project-2/ci/shared.yml

project-job:
  stage: test

  variables:
    FROM_PROJECT: "default-in-provider-project"

  script:
    - echo "FROM_PROJECT=${FROM_PROJECT}"

実行結果

  • check-local(ローカルジョブ)と project-job(外部ジョブ)がどちらもパイプラインに表示される
  • すべてのジョブが成功
  • FROM_PROJECT=overridden-in-runner-test-project-1 が出力され、実行側の変数が優先されることを確認

ポイント

変数の上書き:同じ名前の変数が複数定義されている場合、最終的にはメインの.gitlab-ci.ymlファイルで定義された値が優先されます。外部ファイル側はデフォルト値を置き、環境依存の値はメイン側で上書きするのがベストです。

権限:実行するユーザーが参照先リポジトリを読む権限を持っている必要があります。安定運用のためには、参照元・参照先を同じグループ内にまとめておくとよいでしょう。

ref の固定:main を参照すると、外部ファイルの変更が即座に反映されてしまうため、安定性を重視するなら、タグやリリースブランチを指定するのがおすすめです。

参考:Use CI/CD configuration from other files | GitLab Docs

extends機能:共通設定の継承

extendsは、ジョブごとに共通する設定をテンプレートとしてまとめ、そこから継承できる仕組みです。同じ処理や変数を繰り返し記述せずに済むのが大きな特徴です。今回の検証では、共通設定を.default-templateとして定義し、job_aではそのまま継承、job_bでは一部の変数を上書きする形を確認しました。

検証環境

  • 任意のプロジェクトに extends-gitlab-ci.yaml を作成し、次の内容を記述しました。

設定例

stages: [test]

# 共通設定(テンプレート)

.default-template:
  stage: test
  image: registry.gitlab.local.example.com/root/registry-project/alpine:latest
  tags:
    - devsecops-runner

  before_script:
    - echo "BEFORE(from base) run common setup"

  variables:
    BASE_VAR: from-base
    OVERRIDE_ME: from-base

# 継承のみ(上書きなし)
job_a:
  extends: .default-template
  script:
    - echo "A BASE_VAR=$BASE_VAR OVERRIDE_ME=$OVERRIDE_ME"
    - echo "A IMAGE=$(cat /etc/alpine-release 2>/dev/null || echo unknown)"

# 一部上書き(variables を上書き)
job_b:
  extends: .default-template
  variables:
    OVERRIDE_ME: from-job-b
  script:
    - echo "B BASE_VAR=$BASE_VAR OVERRIDE_ME=$OVERRIDE_ME"

実行結果

  • すべてのジョブが成功
  • job_a
    • BASE_VAR=from-base
    • OVERRIDE_ME=from-base
    • before_script の “BEFORE(from base) run common setup” が実行され、image も alpine:latest が利用されている
  • job_b → 変数 OVERRIDE_ME はジョブ側の値で上書き、BASE_VAR や before_script はテンプレートの値がそのまま反映されている
    • BASE_VAR=from-base(テンプレートのまま)
    • OVERRIDE_ME=from-job-b(ジョブ側の値で上書き)
    • before_script と image はテンプレートの設定が適用されている

ポイント

共通化のメリット:before_script や変数をテンプレートにまとめることで、修正が必要になった際に1箇所を直すだけで全ジョブに反映できます。結果として、ジョブテンプレートの管理や保守がシンプルになり、影響範囲も明確に把握できます。

変数の上書き:テンプレートとジョブの両方に同じキーが定義されている場合、ジョブで定義された値が優先されます。テンプレートは共通の値を設定し、必要に応じてジョブ側で上書きするのが基本的な使い方です。

参考:Optimize GitLab CI/CD configuration files

まとめ

  • includeを使うと、外部ファイルを取り込んで 共通ジョブを複数のプロジェクトで再利用できます。
  • extendsを使うと、共通設定をテンプレート化してジョブごとの差分だけを簡潔に記述できます。
  • どちらの機能も、複雑化しやすい .gitlab-ci.yml を整理し、変更や保守を効率化するために欠かせない仕組みです。

チームやプロジェクトが大きくなるほど、パイプラインの管理は難しくなります。include とextendsを活用すれば、CI/CD 設定をシンプルかつ再利用性の高い形に整え、大規模な開発環境でも安定して運用できる基盤を作ることができます。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です