GitLab Self-Managed と AWS CodeBuild による Self-managed runners の連携

記事タイトルとURLをコピーする

こんにちは。
アプリケーションサービス部、DevOps担当の兼安です。

今回は、GitLab Self-Managed と AWS CodeBuild を連携して、Self-managed runners を利用する方法について紹介します。
長めの記事になりますが、最後までお付き合いいただければ幸いです。

本記事のターゲット

本記事はGitLabのやや上級者向けの記事となります。
GitLab、CI/CD、AWS CodeBuildに関する基本的な知識をお持ちの方を対象としています。
GitLab CI/CDでの実行負荷を分散させたいという需要に向けた記事です。 GitLab CI/CDの基本的な使い方を理解していることを前提としています。

本記事の検証環境

  • GitLab
    • バージョン:GitLab Enterprise Edition 18.6
    • ホスティング環境:Amazon EC2 (Amazon Linux 2023)

本記事に出てくる用語

用語 説明
GitLab Self-Managed 自社でホスティングされたGitLabインスタンス
本記事ではAmazon EC2上に構築されたGitLabを指します
Self-managed runners GitLab CI/CDで使用される自己管理型ランナー
本記事ではAWS CodeBuild上で動作するRunnerを指します
Runner GitLab CI/CDでジョブを実行するためのコンポーネント
GitLabからジョブを取得し、executorに応じた実行環境でジョブを実行します
executor Runnerがジョブを実行する際の実行方式
Shell Executor Runnerがジョブを実行する際の実行方式の一つ
ホスト上で直接コマンドを実行します
本記事のCodeBuild上のRunnerはShell Executorで動作します
AWS CodeBuild AWSのフルマネージド型ビルドサービス
本記事ではGitLab Self-Managed Runnerが動作する基盤として使用します
プロジェクト GitLabにおけるリポジトリの単位
本記事ではGitLab Self-Managed上のプロジェクトを指します
Webhook イベントが発生した際に指定されたURLにHTTPリクエストを送信する仕組み
GitLabからCodeBuildへのイベント駆動型の呼び出し機構として使用され、GitLab側のCI/CDパイプラインイベントをトリガーにCodeBuildでビルドを自動実行します

本記事におけるSelf-managed runnersまでの動作フロー

本記事で構築する環境においては、GitLab CI/CDパイプラインが実行されると、Webhookを介してAWS CodeBuildにHTTPリクエストが送信されます。
CodeBuild上で起動したコンテナ内でGitLab RunnerがShell Executorとして動作します。
RunnerはGitLab Self-Managedからジョブを取得し、同一コンテナ内で直接ジョブを実行します。
ジョブの実行結果はGitLab Self-Managedに報告されます。

ジョブ実行の全体フロー

graph TD
    A[GitLab Self-Managed<br/>EC2上のGitLabインスタンス] -->|1. CI/CDパイプライン実行| B[Webhook]
    B -->|2. HTTPリクエスト送信| C[CodeBuild]
    C -->|3. コンテナ起動| D[CodeBuildコンテナ]
    D -->|4. Runner起動| E[GitLab Self-managed runners<br/>Shell Executor]
    E -->|5. ジョブ取得| A
    E -->|6. ジョブ実行<br/>同一コンテナ内で直接実行| D
    D -->|7. 実行結果報告| A

CodeBuildコンテナ内での詳細な処理フロー(デフォルト動作)

CodeBuildコンテナが起動した後、以下の処理が実行されます。
以下はデフォルトの動作をイメージしたフローです。

graph TD
    A[Webhookトリガー] -->|ビルド開始| B[CodeBuildコンテナ起動]
    B --> C[Runner登録]
    C --> D[GitLabへRunner登録<br/>Ephemeral Runner]
    D --> E[GitLab Runnerプロセス起動<br/>Shell Executor]
    E --> F[GitLabからジョブ情報取得]
    F --> G[GitLabからソースコードをクローン]
    G --> H[.gitlab-ci.ymlの<br/>scriptセクションを実行]
    H --> I[ビルド・テスト実行]
    I --> J[GitLabへ実行結果報告]
  • CodeConnectionsはCodeBuildとGitLabの連携のための接続に使われます
  • CodeBuildのGitLab Runnerは、Runner(コントローラー)兼Executorとして動作し、ジョブを実行します
  • buildspec-override:trueタグを.gitlab-ci.ymlのtagsに追加すると、buildspecコマンドも実行できます

AWS CodeBuildによるSelf-managed runnersの構築手順

本章では、AWS CLIを使用してSelf-managed runnersを構築する手順を説明します。
今回は、GitLab Self-Managedの構築手順は割愛します。

前提条件

  • VPC内のEC2上でGitLab Self-Managedが稼働していること
  • GitLab Self-Managedが、Developer Tools(CodeConnections、CodeBuild)からのHTTPSアクセスが可能になっていること

VPCによるプライベート通信の構成は別の機会で述べます。

個人用アクセストークン(PAT)の作成

GitLab Self-Managed側で、個人用アクセストークン(PAT)を作成します。

  • GitLabにログインする
  • 右上のユーザーアイコンをクリックし、「Preferences」(設定)を選択
  • 左側のメニューから「Personal Access Tokens」(個人用アクセストークン)を選択
  • 「Add new token」
    • スコープでapiを選択
    • 今回はAWS連携のみを目的としているため、api以外にチェックをしなくても後述の動作が確認できました
  • Create personal access token(個人用アクセストークンを作成)ボタンをクリック

PreferencesからPersonal Access Tokensをクリック

api にチェック

GitLab Self-ManagedとのCodeConnectionsの作成

AWS マネジメントコンソールの、デベロッパー用ツール > 接続 で、GitLab Self-Managed用の接続(=CodeConnections)を作成します。

デベロッパー用ツールで接続を作成し、GitLab Self-Managedを選択

プロバイダーで、「GitLab Self-Managed」を選択します。
URLはHTTPS接続である必要があります。
この時、自己署名証明書だと接続自体は作成できますが、その後のPAT入力時にエラーが発生する時があるので注意してください。
(私も失敗しました)

今回はVPC設定はなしで構築します。
VPC設定ありの設定方法は、別途記事を作成予定です。

作成が完了すると、「保留中の接続を更新」というリンクが表示されます。
リンクをクリックすると、GitLabのパーソナルアクセストークン(PAT)を入力する画面に遷移するので、先ほど作成したPATを入力してセットアップを完了します。

「保留中の接続を更新」のリンクをクリック

PAT入力画面

CodeBuildが使用するIAMロールの作成

CodeBuildが使用するIAMロールをコマンドで作成します。

AWSCodeBuildDeveloperAccessはCodeBuildの基本的な操作を行うために必要なポリシーです。
CodeConnectionsへのアクセス権限も追加で付与します。
信頼ポリシーでは、CodeBuildサービスがこのロールを引き受けることを許可しています。

# 変数の設定
ROLE_NAME="<role-name>"

# 信頼ポリシーの作成
cat > trust-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "codebuild.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

# CodeConnections用のポリシーの作成
cat > codeconnections-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "codeconnections:GetConnectionToken",
        "codeconnections:GetConnection",
        "codeconnections:UseConnection"
      ],
      "Resource": "*"
    }
  ]
}
EOF

# IAMロールの作成
aws iam create-role \
  --role-name ${ROLE_NAME} \
  --assume-role-policy-document file://trust-policy.json

# 必要なマネージドポリシーのアタッチ
aws iam attach-role-policy \
  --role-name ${ROLE_NAME} \
  --policy-arn arn:aws:iam::aws:policy/AWSCodeBuildDeveloperAccess

aws iam attach-role-policy \
  --role-name ${ROLE_NAME} \
  --policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess

# CodeConnections用のインラインポリシーを追加
aws iam put-role-policy \
  --role-name ${ROLE_NAME} \
  --policy-name CodeConnectionsAccess \
  --policy-document file://codeconnections-policy.json

CodeBuildプロジェクトの作成

GitLab Self-Managed Runner用のCodeBuildプロジェクトを作成します。
AWSマネジメントコンソールのCodeBuildからプロジェクトを作成します。

プロジェクトタイプは、「ランナープロジェクト」を選択し、「GitLab Self-Managed」を選択します。
この時、CodeConnectionの設定が完了していれば、「アカウントは CodeConnections 経由で正常に接続されました。」と表示されると思います。

CodeBuildでランナープロジェクトを作成

リポジトリの欄には、GitLab Self-ManagedのプロジェクトのURLを指定します。

リポジトリの指定

「環境」セクションの、「サービスロール」で、先ほど作成したIAMロールを指定します。
RunnerとしてCodeBuildを使用する場合、作成時にWebhookが自動作成されます。
この時、CodeConnectionを使用してGitLab Self-Managedの認証などを行うため、CodeConnection系のポリシーがないとWebhookの作成に失敗します。

サービスロールの指定

その他の設定はデフォルトのままで問題ありません。
CodeBuildプロジェクトの作成が完了すると、GitLab Self-Managedのプロジェクト設定画面で、Webhookが自動作成されていることが確認できます。

GitLab側でWebhookが自動作成されていることを確認

GitLabプロジェクトでの.gitlab-ci.ymlの設定

GitLabプロジェクトのルート直下に.gitlab-ci.ymlファイルを作成し、CodeBuildをRunnerとして使用するように設定します。

workflow:
  name: CodeBuild Runner Pipeline

stages:
  - npm
  - aws

npm-job:
  stage: npm
  script:
    - echo "Installing npm packages..."
    - npm install
  tags:
    - codebuild-<project-name>-$CI_PROJECT_ID-$CI_PIPELINE_IID-$CI_JOB_NAME
aws-cli-job:
  stage: aws
  script:
    - echo "Using AWS CLI in CodeBuild..."
    - aws s3 ls
  tags:
    - codebuild-<project-name>-$CI_PROJECT_ID-$CI_PIPELINE_IID-$CI_JOB_NAME

tagsの役割

CodeBuild Self Managed Runnerを使用する際、tagsの設定が重要です。

  • 1つ目のタグ
    • 必須のタグです。
    • <project-name>: CodeBuildで作成したプロジェクト名を指定(必ずプロジェクト名と一致させる必要があります)
    • $CI_PROJECT_ID$CI_PIPELINE_IID$CI_JOB_NAME: GitLabの変数で、ビルドを特定のパイプラインジョブにマッピングし、キャンセル時にビルドを停止するために必要
  • 2つ目以降のタグ(任意)
    • 今回は指定していませんが、必要に応じて使用するDockerイメージやインスタンスサイズ、フリートを指定できます

構築手順は以上です。

動作確認

GitLabプロジェクトに変更をプッシュし、CI/CDパイプラインが正常に実行されることを確認します。
CI/CDの画面では、以下のように表示されます。

GitLab本体上でジョブが実行されているように見えますが、実際にはCodeBuild上でジョブが実行されています。

GitLabのCI/CD画面

CodeBuildのビルド履歴

RunnerにCodeBuildを使用した場合、OIDCは必須ではない

GitLab CI/CDからAWSのリソースにアクセスする場合、OIDCを使用して一時的な認証情報を取得する方法があります。
今回の構成では、RunnerがCodeBuild上で動作しているため、CodeBuildのIAMロールを使用してAWSリソースにアクセスできます。
したがって、.gitlab-ci.ymlでOIDC接続を記述する必要はありません。

まとめ

Self-managed runnersをAWS CodeBuild上で動作させる方法を紹介しました。
CodeBuildを使用することで、GitLab Self-Managedの負担を軽減し、スケーラブルなCI/CD環境を構築できます。
今回はVPCを使用しない構成としていたため、VPCを使用した構成は別の機会に述べたいと思います。

参考

兼安 聡(執筆記事の一覧)

アプリケーションサービス部 DS3課所属
2025 Japan AWS Top Engineers (AI/ML Data Engineer)
2025 Japan AWS All Certifications Engineers
2025 AWS Community Builders
Certified ScrumMaster
PMP
広島在住です。今日も明日も修行中です。
X(旧Twitter)