マイクロサービス
をモノレポ
(単一レポジトリ)で管理している場合、ルートに置かれた.gitlab-ci.yml
のみで記述しているとファイルが肥大化する傾向にあります。 また、フロント/バックエンドのソースを単一レポジトリに含めている場合も同様です。
マイクロサービスなどの独立してデプロイ可能な単位のソースを、別々のレポジトリで管理する場合もあると思いますが、特にプログラムの規模がさほど大きくない場合は、単一のレポジトリで管理したほうが、扱いやすいと思います。
ちなみに Wikipediaには、GoogleやFacebookなどでも非常に大規模なソースを モノレポ
構成で管理しているように書いてあります。1 (英語ではmonorepo=モノレポ)
Google,[5] Facebook,[6] Microsoft,[7] Uber,[8] Airbnb and Twitter[9] all employ very large monorepos with varying strategies to scale build systems and version control software with a large volume of code and daily changes.
今回は、GitLab 12.7
で導入された、親子関係のパイプライン
と Only
と Changes
キーワードを組み合わせた構成をご紹介します。
モノリシック
なサービスの場合や、単純に .gitlab-ci.yml
が肥大化した場合の対処法としては、 include
キーワードでファイルを分けたり、 extends
キーワードでリファクタリングする方法があると思います。
構成案
レポジトリのディレクトリ構成例
+ .gitlab-ci.yml # ルートにあるCI/CD構成スクリプト
+ my_service_a # デプロイ可能なソースディレクトリ
| + .my_service_a.yml
| + ...
+ my_service_b # 別のデプロイ可能なソースディレクトリ
| + .my_service_b.yml
| + ...
| ...
- 仮にサービスのディレクトリが更に深いサブディレクトリにあっても問題なし。
親パイプラインの定義
.gitlab-ci.yml
の中身
image: alpine:3.7 # 参考用に軽いalpineに変更
stages:
- triggers
my_service_a:
stage: triggers
only:
refs: # ブランチを限定する場合
- develop
- stage
changes: # 以下ディレクトリ内に変更があった場合のみトリガーされる
- my_service_a/**/*
trigger:
include: my_service_a/.my_service_a.yml # 子パイプライン定義
strategy: depend
my_service_b:
stage: triggers
only:
refs: # ブランチを限定する場合
- develop
- stage
changes: # 以下ディレクトリ内に変更があった場合のみトリガーされる
- my_service_b/**/*
trigger:
include: my_service_b/.my_service_b.yml # 別の子パイプライン定義
strategy: depend
ポイント
- ステージはtriggersのみ
- デプロイ可能な単位に列挙(下記では my_service_a, my_service_b)
- only > refs は ブランチを限定
- only > changes は プッシュ時に変更があった場合のみトリガーさせる
- trigger キーワードで、参照先のスクリプトを指定
- strategy: depend で子パイプラインがすべて成功するまで親も成功ステータスにしない。
子パイプラインの定義
.my_service_a.yml
(中身は自由ですが参考までに一応記載)
image: alpine:3.7
stages:
- one
- two
- three
stage_one_one:
stage: one
script:
- echo "ONE"
stage_two_one:
stage: two
script:
- echo "TWO ONE"
stage_two_two:
stage: two
allow_failure: false
only:
refs:
- develop
script:
- echo "TWO TWO"
stage_three_two:
stage: three
when: on_success
only:
refs:
- develop
script:
- echo "THREE TWO"
トリガーさせる
developブランチで、my_service_a/
または my_service_b/
のディレクトリ配下のソースをコミットしてリモートへプッシュ。
まとめ
- 各種デプロイ可能なディレクトリのルートにCI/CDの構成を書くことで分かりやすくなった。
- Changes キーワードを利用することで、コミット時に変更がある場合のみに実行し、無駄な実行を省いた。
-
デメリットとして、小パイプラインのスクリプトのコード共通化の範囲は一部限定される。(例: .my_service_a.yml ⇔ .my_service_b.ymlの間)include
キーワードで共通のコンフィグを外部ファイル化すれば、サービス間のコンフィグのリファクタリングも可能。