皆様こんにちは。SEの小池と申します。
以前、GitLabのCI/CDパイプラインのキーワード解説で workflow
を取り上げました。(こちら)
ほぼ筆者の自習メモと化しているこのキーワード解説の第2弾をお送りいたします。
今回はキーワード include の概要と具体例を用いた説明をします。
- 本記事の対象の方
- 今回のブログのゴール
- このブログをお読みいただくにあたっての事前ご連絡事項
- キーワード include の概要
- キーワード include のユースケース
- include の超簡単な使い方の例
- 注意点:「そのジョブを実行するステージがないよ」エラー
- 最後に
本記事の対象の方
- GitLabのCI/CDパイプラインで
.gitlab-ci.yml
ファイルを分割したい方。 - GitLabのCI/CDパイプラインで、別のプロジェクトの
.gitlab-ci.yml
ファイルを参照させたい方。 - GitLabのCI/CDパイプラインのキーワード
include
について情報収集中の方。 - 他人が書いた
.gitlab-ci.yml
でinclude
が多用されてて意味が分からず困っている方。
今回のブログのゴール
このブログのゴールはこちらです。
- GitLabのCI/CDパイプラインのキーワード include の概要を把握する。
このブログをお読みいただくにあたっての事前ご連絡事項
- 本記事はSaaS版 (GitLab.com) の Enterprise Edition 15.7.0-pre における仕様をベースに記載しております。それ以外のエディションやバージョンではこの記事に記載の通りではない可能性がございます。
- 本記事はGitやCI/CDに関する知識ゼロのSEによるなんちゃって記事です。GitLabのディープな使用法についてはGitLabの公式オンラインドキュメント (こちら) をご参照ください。
キーワード include の概要
include
は、外部のyamlファイルをCI/CDパイプラインに含めることができるグローバルキーワードです。
GitLabは、基本的にはプロジェクトのリポジトリのルートにある.gitlab-ci.yml
ファイルにCI/CDパイプラインの構成を記載します。
ただ、CI/CDパイプラインの内容が複雑になりすぎて1つのファイルに書ききれない、既にある別のプロジェクトのパイプラインを引用したい…といったご要望もあると存じます。
そういったときにinclude
を使うことで、リポジトリのルートにある .gitlab-ci.yml 以外のyamlファイルをそのCI/CDパイプラインに取り込むことができます。
概念をイメージ図で説明いたします。
まず、GitLabの任意のプロジェクトのリポジトリに、下図のようなファイルやディレクトリがあるとします。
ファイル.gitlab-ci.yml
にはステージ build で実行する ジョブ ビルドジョブ01 が構成されています。
ファイルtest.gitlab-ci.yml
にはステージ test で実行する ジョブ テストジョブ01 が構成されています。
イメージ図をわかりやすくするためにyamlファイルの中で日本語を使っています。ご了承ください・・・。
この状態でCI/CDパイプラインを実行すると、パイプラインにはステージ build と、ジョブ ビルドジョブ01 が生成・実行されます。
つまり、ファイル.gitlab-ci.yml
で構成したステージとジョブしか生成されず、ファイルtest.gitlab-ci.yml
で構成したステージとジョブは生成されません。
ここで、ファイルtest.gitlab-ci.yml
で構成したステージとジョブをCI/CDパイプラインで実行するために、キーワードinclude
を使ってみましょう。
ファイル.gitlab-ci.yml
に、キーワードinclude
と含める対象のyamlファイル名を記載します。
この状態でCI/CDパイプラインを実行すると、パイプラインにはステージ build と test、ジョブは ビルドジョブ01 と テストジョブ01 が生成・実行されます。
この様にキーワードinclude
を使用すると、ファイル.gitlab-ci.yml
以外のyamlファイルに記載されたCI/CDパイプラインの構成を含めることができます。
この様に、include
は外部のyamlファイルをCI/CDパイプラインに含めることができます。
先述のイメージ図では同じリポジトリにある異なるyamlファイルをincludeしましたが、以下のいずれかに該当するyamlファイルであればincludeすることができます。
なお、remoteの場合は認証をサポートしていないなどの制限があります。詳細はGitLab Docs (こちら) をご参照ください。
- 同じプロジェクトのリポジトリにあるyamlファイル (local)。
- 異なるGitLabプロジェクトのリポジトリにあるyamlファイル (project)。
- HTTP/HTTPS リクエストでアクセスできる公開URLに存在するyaml (remote)。
- テンプレートにあるyamlファイル (template)。
includeはグローバルキーワードです。
したがって、includeはジョブの中で指定することはできません。
またyamlファイルの一部分だけを抜き出してincludeすることはできません。
キーワード include のユースケース
アプリケーション開発をしたことがない筆者が頑張って考えたキーワードinclude
のユースケースを挙げます。
- yamlファイルの肥大化を防ぐために、分割したい場合。
- 同じGitLabインスタンスの別のプロジェクトで利用しているyamlファイルを再利用可能な場合。
- GitLabのリポジトリ以外で保管しているyamlファイルを参照したい場合。
- GitLabが公開しているテンプレートを利用する場合。
上記のほかにも少し応用的な使い方として、キーワードinclude
とキーワードrules
を併せて使うことで、特定の条件を満たした時だけ任意のyamlファイルを含めるような処理を構成することも可能です。
例えば以下のような.gitlab-ci.yml
ファイルの場合、別の2つのyamlファイルをincludeしていますが、このうちtemplate
で指定された方のyaml (9行目に指定されたyaml) にだけ「ローカルリポジトリのルートにreadme.mdがある場合にのみ含める」という条件が付いています。
buildjob01: stage: build script: - echo ステージ1のテストのジョブです。 - sleep 10 include: - local: '/sample-dir/sample-security.yml' - template: Security/SAST.gitlab-ci.yml rules: - exists: - "readme.md"
単純にyamlファイルを見やすくしたり、汎用的なyamlを参照させるだけでなく、上記のようにキーワードrules
を併せて使うことで「○○の時だけこのyamlファイルをincludeする」といったように条件を指定できます。
include の超簡単な使い方の例
ここからは実際にキーワードinclude
の使い方を、超簡単な例を用いて紹介してまいります。
ローカルに存在する別のyamlファイルを含める場合 (local)
ローカル、つまり、同じプロジェクトのリポジトリに存在する別のyamlを含める場合、明示的に include:localと指定するか、もしくはサブキーワードの指定なしで記載します。
ここでは、ローカルにある/test/sample.gitlab-ci.yml
を含めると仮定します。
ローカルにある/test/sample.gitlab-ci.yml
の内容は以下の通りであると仮定します。
testjob01: stage: test script: - echo このジョブはtestステージで実行されるサンプルジョブです。 - sleep 10
includeする側である.gitlab-ci.yml
で、明示的にinclude:local
と指定する場合は以下 (7, 8行目) のような記載になります。
buildjob01: stage: build script: - echo このジョブはbuildステージで実行されるサンプルジョブです。 - sleep 10 include: - local: '/test/sample.gitlab-ci.yml'
キーワードinclude
はサブキーワードを指定しない場合はデフォルトでローカルのリポジトリをチェックするので、以下 (7行目) のようにlocal
を省略することも可能です。
buildjob01: stage: build script: - echo このジョブはbuildステージで実行されるサンプルジョブです。 - sleep 10 include: '/test/sample.gitlab-ci.yml'
明示的にinclude:local:
を書いた場合も、local:
を省略した場合も同様に、CI/CDパイプラインはこんな感じになります。
同じプロジェクトのリポジトリに存在するファイルを含めているだけなので、とてもシンプルな使い方です。
キーワードinclude
の試行や練習をする場合は、まずはローカルのyamlファイルのincludeからお試しいただくのがよいと存じます。
同じGItLabインスタンスの別プロジェクトに存在するyamlファイルを含める場合 (project)
同じGItLabインスタンスの別プロジェクトに存在する別のyamlを含める場合、そのプロジェクトのパスと、ファイルのパスを指定する必要があります。
includeしたいyamlファイルがあるプロジェクトをサブキーワードproject
、yamlファイルのパスをfile
でそれぞれ指定します。
ここでは、IncludeTestPJ01 というプロジェクトにある/sample-dir/sample-security.yml
を含めると仮定します。
また、プロジェクト IncludeTestPJ01 にある/sample-dir/sample-security.yml
の内容は以下の通りであると仮定します。
samplejob01: stage: test script: - echo これはプロジェクト IncludeTestPJ01 の /sample-dir/sample-security.yml です。 - sleep 10
前述の通り、別プロジェクトに存在するyamlを含める場合は、以下の記載例のようにincludeしたいyamlファイルがあるプロジェクトをサブキーワードproject
、yamlファイルのパスをfile
でそれぞれ指定する必要があります。
# ### 記載例 ### # ex.) 異なるプロジェクトに存在するyamlファイルをincludeする場合。 include: - project: '<includeしたいyamlファイルが存在するプロジェクトのパス>' file: '<includeしたいyamlファイルのパス>'
サブキーワードproject
に指定するプロジェクトのパスは、プロジェクトのURLからGitLabのFQDNやIPを除いた文字列となります。
このブログの例の場合、プロジェクトのURLはhttps://gitlab.com/ssg6/yaml-pj/includetestpj01
なので、サブキーワード project で指定する値はssg6/yaml-pj/includetestpj01
です。
つまり、今回のようにプロジェクトパスssg6/yaml-pj/includetestpj01
にある、yamlファイル/sample-dir/sample-security.yml
をincludeしたい場合は以下のように記載します。
buildjob01: stage: build script: - echo ステージ1のテストのジョブです。 - sleep 10 include: - project: 'ssg6/yaml-pj/includetestpj01' file: '/sample-dir/sample-security.yml'
上の.gitlab-co.yml
で構成されるCI/CDパイプラインは以下のようになります。
GitLabで汎用的に使用できるCI/CDパイプラインを構成しているyamlがある場合は、サブキーワードprojectでincludeする方法がかなり有効です。
社内やグループでCI/CDパイプラインを使用することが定着しているのであれば、参照専用のプロジェクトを作成して、そこにあるyamlファイルをincludeする運用をご検討いただくのもよいかと存じます。
任意のURLに存在するyamlファイルを含める場合 (remote)
任意のURLで公開されているyamlファイルを含める場合、そのファイルのURLをサブキーワードに指定する必要があります。
ここでは例として、Amazon S3で公開している以下のyamlファイルをincludeしてみます。
samplejob01: stage: test script: - echo これはAmazon S3で公開しているyamlファイルです。 - sleep 10
サブキーワードremote
を用いたincludeの書き方は以下の通りです。
# ### 記載例 ### # ex.) 任意のURLに公開されているyamlファイルをincludeする場合。 include: - remote: '<yamlファイルが公開されているURL>'
例として、Amazon S3で公開したyamlファイルのURLがhttps://tkoike-gitlab-yaml-koukai-20221214.s3.ap-northeast-1.amazonaws.com/awss3.gitlab-ci.yml
とすると、.gitlab.ci-ymlは以下のようになります。
buildjob01: stage: build script: - echo ステージ1のテストのジョブです。 - sleep 10 include: - remote: 'https://tkoike-gitlab-yaml-koukai-20221214.s3.ap-northeast-1.amazonaws.com/awss3.gitlab-ci.yml'
上の.gitlab-co.yml
で構成されるCI/CDパイプラインは以下のようになります。
サブキーワードremote
を使う場合は、認証がサポートされていませんのでご注意ください。(2022/12/15時点)
テンプレートとして存在するyamlファイル含める場合 (template)
サブキーワードtemplate
は中央リポジトリ (こちら) にあるyamlファイルをincludeできます。
GitLabが売りにしている機能の一つに Auto DevOps というものがありますが、Auto DevOpsの実装の一部でもこのサブキーワードを使います。
サブキーワードtemplate
の記載例は以下の通りです。
テンプレートのパスは、中央リポジトリであるこちらを基準とした相対パスを指定する必要があります。
# ### 記載例 ### # ex.) サブキーワードtemplateの指定方法。 include: - template: '<GitLabの中央リポジトリに存在するyamlファイルへの基準とした相対パス>'
Auto DevOpsの一つであるSASTを実装する場合を例に挙げます。
2022/12/15現在、SASTのテンプレートは中央リポジトリからの相対パスSecurity/SAST.gitlab-ci.yml
にあります。
これをサブキーワードtemplate
に指定します。
このSASTテンプレートをincludeする例がこちらです。
buildjob01: stage: build script: - echo ステージ1のテストのジョブです。 - sleep 10 include: - template: Security/SAST.gitlab-ci.yml
上の.gitlab-ci.yml
で構成されるCI/CDパイプラインは以下のようになります。
なお、SASTのテンプレートにて自動的に構成されるジョブはリポジトリの内容によって変化するため、以下は一例となります。
前述の通りサブキーワードtemplate
は一部のAuto DevOpsの実装時に使うため、初心者でもに目にすることが多いincludeの使い方です。
中央リポジトリからの相対パスが指定されていることを知ってさえいれば、シンプルな使い方のサブキーワードです。
注意点:「そのジョブを実行するステージがないよ」エラー
キーワードinclude
利用時に注意すべき事項があります。
それは、includeする側・される側問わず、yamlファイルの中でキーワード stages を用いてステージを明示的に宣言している場合です。
includeする側・される側問わず、どちらか片方だけでstagesを宣言している場合、stagesを宣言している方のyamlで定義されたステージのみ利用できます。デフォルトのステージである.pre
, build
, test
, deploy
, .post
を含め、stagesで明示的に宣言していないステージは利用することができません。
したがって、stagesを宣言していていない側のyamlに設定したジョブは、stagesを宣言している側のyamlのステージ構成を考慮してジョブを設定する必要があります。
includeする側・される側の両方でstagesを宣言している場合、利用できるステージはincludeする側のyamlで宣言されたステージのみとなります。
したがって、includeされる側のyamlに設定したジョブは、includeする側のyamlのステージ構成を考慮してジョブを設定する必要があります。
以下の図はincludeする側でステージの定義をし、includeされる側でステージの定義をしていない場合です。
ファイル.gitlab-ci.yml
がincludeする側、ファイルsample.gitlab-ci.yml
がincludeされる側です。
この時、ファイルsample.gitlab-ci.yml
にある、ジョブsamplejob02
は実行ステージが sample-stage となっています。
しかし、includeする側の.gitlab-ci.yml
では、ステージ sample-stage が定義されていません。
このため、ジョブsamplejob02
は実行するステージが存在しない状態となり、結果としてCI/CDパイプラインはエラーとなります。
以下の図はincludeする側でステージの定義はせず、includeされる側でステージの定義をしている場合です。
ファイル.gitlab-ci.yml
がincludeする側、ファイルsample.gitlab-ci.yml
がincludeされる側です。
この時、ファイル.gitlab-ci.yml
にある、ジョブbuildjob01
は実行ステージが build となっています。
しかし、includeされる側の.gitlab-ci.yml
では、ステージ build が定義されていません。
このため、ジョブbuildjob01
は実行するステージが存在しない状態となり、結果としてCI/CDパイプラインはエラーとなります。
以下の図はincludeする側・される側の両方でステージの定義をしている場合です。
ファイル.gitlab-ci.yml
がincludeする側、ファイルsample.gitlab-ci.yml
がincludeされる側です。
この場合において利用可能なステージは、includeする側のファイル.gitlab-ci.yml
で定義されたステージです。
つまり、includeされる側のファイルsample.gitlab-ci.yml
のジョブtestjob01
は実行するステージ test がない状態です。
結果としてCI/CDパイプラインはエラーとなります。
この様に、includeする側・される側ともに、yamlファイルで不用意に stages を宣言していると、include時に思わぬところでエラーが出る場合があります。
stages を宣言する場合は、includeする側・される側のyamlファイルの既存ジョブの設定を考慮してください。
stages を宣言しない場合は、デフォルトステージである.pre
, build
, test
, deploy
, .post
でジョブを実行するように設定してください。
また、GitLabのGUIにあるCI/CDパイプラインのエディタを使って.gitlab-ci.yml
を編集すると、ステージがないために実行できないジョブがある場合は編集画面 (GUI) にエラーメッセージが表示される仕様になっているので、ご活用ください。
最後に
この度はGitもCI/CDもよくわかっていないど素人SEによるGitLab検証ブログをお読みいただき、誠にありがとうございます。
このブログの目標は以下のとおりでしたが、皆さまはいかがでしたでしょうか。
- GitLabのCI/CDパイプラインのキーワード include の概要を把握する。
CI/CDパイプラインのキーワードはたくさんあります。
サブキーワードが4種類ありますが、どれも基本的には「別のyamlファイルに記載されたCI/CDパイプライン構成を含める」ということには変わりないので、覚えてしまえばシンプルなキーワードです。
もし、会社やグループで一部のCI/CDパイプラインの汎用化をしている場合、そのyamlファイルの内容をコピーするのではなく、includeで含めるという方法もご検討いただければと存じます。
この記事がGitLabを触り始めた方の一助となれば幸いにございます。
GitLabに関するお問い合わせは、以下のフォームからお願い致します。
GitLab製品 お問い合わせ
GitLab操作デモ動画 (基本編) を作ってみました。(音声の録音は自宅でiPhoneのボイスメモ使うという超低クオリティですが…。)
つたない内容ではありますが、ご興味がおありでしたら是非ご視聴いただければと存じます。