【CI/CD】GitLabのinclude機能を用いて、マイクロサービスのCI設定ファイルをテンプレート化する

はじめに

こんにちは、AI・IoTサービス開発部の岩丸です。 早いもので2年目に突入し後輩が出来ました。年齢も無事にインクリメントされましたので自分らしく2年目も頑張っていきたいと思います。

前回はGCPのCloud Run、Cloud BuildでCIOps環境を構築してみた話を執筆しました。もしお時間ある方は合わせてご覧ください。

tech-blog.optim.co.jp

今回はGitLabのinclide機能を用いてCI/CD設定ファイルのテンプレート化を行ったのでご紹介致します。GitLabは優秀な機能が多いのでどんどん活用していきたいです。

目次

やりたいこと

マイクロサービス構成で構成されたプロダクトは新機能の開発や不具合の改修・デプロイが非常に高速かつ柔軟に行えるのが魅力です。 ただ、小さく・速く実装できるためリポジトリの数が自然と増えていく傾向にあります。両手で数えられるくらいの量であれば良いですが数十のリポジトリになってくると管理するのが非常に大変になります。

CI観点でみたデメリットとして各リポジトリで.gitlab-ci.ymlを管理するということがあります。 イメージの脆弱性スキャン対応やデプロイ・テストなどの共通処理を追加したい場合、それぞれのリポジトリで対応することになりリポジトリの数だけ対応工数が増加します。 また、.gitlab-ci.ymlを各リポジトリで適切に管理する必要があり対応漏れが発生する恐れがあります。

そこでGitLabのinclude機能を用いて.gitlab-ci.ymlのテンプレート化できないか考えました。

include機能とは

include機能とは外部のYAMLファイルを利用するための機能です。includeの方法としてlocalfileremotetemplateをサポートしており、別リポジトリのみならず、リモートURLが参照可能な公開済みリポジトリのYAMLファイルもincludeすることができます。

include機能と同じように.gitlab-ci.ymlの肥大化を防ぐ機能としてtrigger機能などもございます。モノレポ構成の場合はこちらの方が有用である可能性が高いです。 trigger機能については以下の記事で詳しく実験されておりました(本記事ではtrigger機能は利用しておりません)。

triggerを使って.gitlab-ci.ymlを分割する | DevelopersIO

やったこと

テンプレートの構成

今回は以下のような構成でテンプレートを作成いたしました。各言語プロジェクト用のyamlファイルをテンプレート化し、それぞれのリポジトリでincludeするという構成です。

/Templates/Gradle.gitlab-ci.yml

実際に作成したテンプレートは以下のようになっています。こちらはGradleプロジェクトのテンプレート例です。

GitLab公式が公開しているテンプレートの開発ガイドラインGradleテンプレートを参考にして実装しています。

#
# Gradle プロジェクトのビルドおよびテストを実行する GitLab Runner テンプレート
#
# Requirements:
# - build stage: コンパイルを実行する
# - test stage: build stage で生成した jar を用いて test を実行する
#   - ref: https://docs.gradle.org/current/userguide/building_java_projects.html
#

default:
  image: gradle:7.4-jdk11

workflow:
  rules:
    - if: $CI_COMMIT_TAG
      when: never
    - when: always

variables:
  GRADLE_OPTS: "-Dorg.gradle.daemon=false"
  TZ: Asia/Tokyo

.gradle_before_script: &gradle_before_script
  - cd app/
  - export GRADLE_USER_HOME=`pwd`/.gradle

build:
  stage: build
  before_script:
    - *gradle_before_script
  script:
    - gradle --build-cache assemble
  cache:
    key: "CI_COMMIT_REF_NAME"
    policy: push
    paths:
      - /app/build
      - /app/.gradle

test:
  stage: test
  before_script:
    - *gradle_before_script
  script:
    - gradle check
  cache:
    key: "CI_COMMIT_REF_NAME"
    policy: pull
    paths:
      - /app/build
      - /app/.gradle

やってみて

今回のテンプレート化で以下の2点の恩恵を受けることができました。

  • テンプレートファイルの対応のみで済むため、対応工数が大幅に削減された
  • 対応漏れがなくなり、対応漏れを確認する時間が削減された

修正対応を行う箇所がテンプレートファイル1箇所になったため、対応工数が大幅に削減出来ました。

また、イメージバージョンの更新や脆弱性対応、イメージの脆弱性スキャンなど、共通の対応を各リポジトリで行う場合、対応漏れがないか逐一確認していました。 そのバージョンにおける対応リポジトリの数が増えれば増えるほど確認でかなりの工数が発生していたため、その工数を大幅に削減できたのは大きいです。

おわりに

今回はGitLabのinclude機能を用いてCI設定ファイルのテンプレート化を行いました。CI/CD周辺は普段の開発・運用工数に直結してくる問題のため、少しずつ改善して注力すべきタスクに注力できるような時間をどんどん捻出していきたいです。 今後もGitLabやDevOpsに関連した記事を執筆していけたらと思います。


そんなOPTiMではDevOpsに興味があるエンジニア、新卒からどんどんチャレンジしていきたいエンジニア学生を随時募集しております。少しでもご興味のある方はこちらも合わせてご覧ください。

www.optim.co.jp