APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

GitLab Service accountとReviewdogを使ってCloudFormationテンプレートをレビューする

こんにちは、クラウド事業部 CI/CDサービスメニューチームの山路です。

今回はGitLab Service accountとReviewdogを組み合わせた例を紹介します。Service accountは有効期限のないアクセストークンを発行できます。発行したトークンをReviewdogに渡して利用すると、トークンの期限を気にせずReviewdogを利用できます。

背景

以前GitLab Service accountについて紹介をしたことがあります。Service accountを使うとBot userを作成し、有効期限のないPersonal access tokenを発行できます。

techblog.ap-com.co.jp

Reviewdogは主にlinterツールの実行結果をもとに、GitLabなどのソースコード管理サービスに対しコメントを残す機能を提供します。Reviewdogを使うことで、CI/CDワークフローの中で実行するlinterで問題を検出すると、問題の内容と修正箇所をコメントで指摘し、開発者やレビュアーが問題箇所に気づきやすくなります。

github.com

一方でReviewdogがMerge requestにコメントを入力するにはPersonal access tokenの設定が必要であり、トークンの有効期限に応じた更新作業などが必要となります。

そこで今回はGitLab Service accountとReviewdogを組み合わせ、トークンの有効期限を気にせずReviewdogを利用できる環境について検証しました。なおReviewdogで利用するlinterと対象のファイルは、cfn-lint / AWS CloudFormationを選びました。

github.com

検証

ここから検証します。検証前に適当なGitLab Projectを用意しておきます。

検証に使うCloudFormationファイルは以下の通りです。ここではcfn-lintにより問題を検出するため、誤って設定する箇所を用意します。

Resources:
  SampleBucket:
    Type: "AWS::S3::Bucket"
    DeletionPolicy: delete # サポートするオプションは Delete / Retain / RetainExceptOnCreateのみです
    Properties:
      VersioningConfiguration:
        Status: Disabled # サポートするオプションは Enabled / Suspendedのみです

次にService accountの作成とPersonal access tokenの発行を行います。詳細な手順やコマンドは以前のブログをご覧ください。

# Service accountの発行
$ curl --request POST \
      --header "PRIVATE-TOKEN:<GitLab token>" \
      "https://gitlab.com/api/v4/groups/<Group ID>/service_accounts"

# Personal access tokenの発行
# トークンの有効期限が設定されていないことを確認してから実行してください
$ curl --request POST \
        --header "PRIVATE-TOKEN: <GitLab token>" \
                 "https://gitlab.com/api/v4/groups/<Group ID>/service_accounts/<Service account ID>/personal_access_tokens" \
        --data "scopes[]=api,read_user,read_repository" \
        --data "name=service_accounts_token_20240917"

Service account作成後は対象のGroupに招待します。

Personal access tokenを発行したら、CI/CD変数画面から REVIEWDOG_GITLAB_API_TOKEN という名称で変数を登録します。

CI/CD変数を設定したら、以下のような .gitlab-ci.yml ファイルを配置します。

cfn-lint:
  image: python:latest
  stage: build
  variables:
    REVIEWDOG_GITLAB_API_TOKEN: $REVIEWDOG_GITLAB_API_TOKEN
    GIT_STRATEGY: clone
    GIT_DEPTH: 0
  before_script:
    - pip install cfn-lint sarif-om jschema_to_python
    - wget -O - -q https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s
  script:
    - cfn-lint -t s3.yaml -f sarif --non-zero-exit-code none | bin/reviewdog -f=sarif -reporter=gitlab-mr-discussion
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      changes:
        - s3.yaml

いくつか補足します。

  • 検証中に failed to get merge-base commit というエラーに遭遇したため、GIT_STRATEGY: clone GIT_DEPTH: 0 という変数を追加しています。
  • cfn-lintコマンド実行時にエラーを検知すると、デフォルトでは終了コードが 1 となるため、後続のJobが実行できない場合があります。そのためここでは --non-zero-exit-code を設定し、エラー検知時もJobを成功するよう設定しています。
  • cfn-lintとReviewdogを組み合わせた場合、Merge requestの作成をトリガーにJobを実行しないとエラーが発生しました。そのため今回はMerge requestの作成と s3.yaml ファイルの修正をトリガーに、Jobを実行するよう設定しました。

.gitlab-ci.yml を配置後、新規ブランチを作成して s3.yaml を修正し、Merge requestを作成します。

しばらく待機するとCI/CDパイプラインが完了し、cfn-lintがいくつかのエラーを検知していることを確認できます。

Merge request画面に戻ると、以下の画像のようにコメントが追加され、エラーの箇所と内容を表示することを確認できます。

なお検証後は必要に応じてService account / Personal access tokenの削除を実施してください。

# Personal access tokenの失効
$ curl --request DELETE \
      --header "PRIVATE-TOKEN:<Service account personal access token>" \
      "https://gitlab.com/api/v4/personal_access_tokens/self"

# Service accountの削除
$ curl --request DELETE \
      --header "PRIVATE-TOKEN:<GitLab token>" \
      "https://gitlab.com/api/v4/groups/<Group ID>/service_accounts/<Service account ID>"

さいごに

弊社はGitLabオープンパートナー認定を受けております。 また以下のようにCI/CDの導入を支援するサービスも行っているので、何かご相談したいことがあればお気軽にご連絡ください。

www.ap-com.co.jp