TerraformでGitLab Self Managedに接続するAWS CodeBuildを自動構築する

# はじめに
以前の記事では、GitLab Self Managedに接続するAWS CodePipelineを作成してみた。

https://qiita.com/neruneruo/items/1535776e5cab5df115bd

ただし、CIのタイミング次第では、必ずしもパイプラインで処理をする必要はなく、たとえばマージリクエスト発行時のように、バッチビルドさえできれば用が足りるケースもある。

また、バッチビルドのプルリクエストへのレポートの書き戻しは、AWS CodePipelineからはマネージドに行ってくれないが、AWS CodeBuildからは行ってくれる。

こういったことを踏まえ、今回は、AWS CodeConnectionsを用いてGitLab Self Managedのマージリクエスト契機でAWS CodeBuildを起動する部分をTerraformで自動構築する方法を検証する。

なお、本記事の構成を構築するにあたり、上記のAWS CodePipelineの記事の、

- GitLabのHTTPS化
- GitLabのトークン払い出し
- 接続(AWS CodeConnections)の設定

まで完了していることを前提とする。

# AWS CodeBuildの設定
## 基本の設定
通常のAWS CodeBuildの設定との違いとして、```source```ブロックの```type```に```GITLAB_SELF_MANAGED```を設定するという点がある。
また、この際の```location```は、GitLabのリポジトリを設定しよう。

```report_build_status```は、AWS CodeBuildのビルド結果をGitLabに書き戻す設定だ。せっかくなので```true```に設定しておこう。

```HCL
resource "aws_codebuild_project" "example" {
  name         = local.codebuild_project_name
  service_role = aws_iam_role.codebuild.arn

  source {
    type      = "GITLAB_SELF_MANAGED"
    location  = "https://${data.aws_instance.smgitlab.public_dns}/${gitlab_group.example.name}/${gitlab_project.example.name}"
    buildspec = "buildspec.yml"
    report_build_status = true
  }

  artifacts {
    type = "NO_ARTIFACTS"
  }

  environment {
    type            = "LINUX_CONTAINER"
    compute_type    = "BUILD_GENERAL1_SMALL"
    image           = "aws/codebuild/amazonlinux2-x86_64-standard:5.0"
    privileged_mode = "true"
  }

  build_batch_config {
    service_role    = aws_iam_role.codebuild.arn
    timeout_in_mins = 480

    restrictions {
      compute_types_allowed  = []
      maximum_builds_allowed = 100
    }
  }

  logs_config {
    cloudwatch_logs {
      group_name = aws_cloudwatch_log_group.codebuild.name
    }
  }

  cache {
    type = "LOCAL"
    modes = [
      "LOCAL_CUSTOM_CACHE",
    ]
  }
}
```

## IAMの権限追加
AWS CodeBuildにアタッチするIAMロールのポリシーに、AWS CodeConnectionsにアクセスするための以下の権限を付与しておこう。

:::note alert
気を付けなければいけないのは、AWS CodeStarConnectionsがAWS CodeConnectionsにリブランドされたからといって、```codeconnections:UseConnection```のアクション権限を付与しても動作しないという点だ。現時点ではあくまでも```codestar-connections:UseConnection```のアクション権限を付与する必要がある。
:::

```diff_HCL
data "aws_iam_policy_document" "codebuild_custom" {
  // (中略)
+ statement {
+   effect = "Allow"
+
+   actions = [
+     "codestar-connections:UseConnection",
+   ]
+
+   resources = [
+     aws_codestarconnections_connection.example.arn,
+   ]
+ }
  // (中略)
}
```

## AWS CodeConnectionsへのアクセス設定
AWS CodeConnectionsには以下のようにアクセスする設定を行う。

```aws_codebuild_webhook```では、何をトリガしてAWS CodeBuildを起動するかを設定する。
```filter_group```で設定している、```HEAD_REF```は、マージリクエストのソースブランチ、```BASE_REF```はターゲットブランチを意味する。
今回は、GitLab Flowのブランチ戦略のセオリーに従い、```feature/任意のブランチ名```から```main```ブランチに対してマージリクエストを発行するケースをトリガする。

詳細は、AWS CodeBuildのユーザーガイドを参照しよう。

https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/gitlab-webhook.html



```HCL
resource "aws_codebuild_source_credential" "example" {
  auth_type   = "CODECONNECTIONS"
  server_type = "GITLAB_SELF_MANAGED"
  token       = aws_codestarconnections_connection.example.arn
}

resource "aws_codebuild_webhook" "example" {
  project_name = aws_codebuild_project.example.name
  build_type   = "BUILD_BATCH"

  filter_group {
    filter {
      type    = "EVENT"
      pattern = "PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED"
    }
    filter {
      type    = "HEAD_REF"
      pattern = "feature/"
    }
    filter {
      type    = "BASE_REF"
      pattern = "main"
    }
  }
}
```

# いざ、動かす！
さて、これで```terraform apply```してから、GitLab Self Managed上でfeature/test1など適当なブランチを作成してマージリクエストを発行すると、AWS CodeBuildが起動するはずだ。

おめでとう！これで、AWS CodeCommitでAmazon EventBridgeを駆使して面倒なプルリクエストのフックを作らなくてもAWS CodeBuildのCIの恩恵に預かることができるようになった！

# と思ったら、ビルド結果が反映されない

![キャプチャ1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/9f9df885-c4f3-88d2-f3cf-3fe5edc9d68a.png)

ビルド結果がマージリクエストのパイプラインに反映されてくれない。
※buildとかtestとか書いてあるのは、GitLabがデフォルトで設定するもの。

どうやら、「集約されたビルド結果」は反映されないらしい。

マネージメントコンソールのAWS CodeBuildの設定画面の「バッチ設定」で、以下の「バッチレポートモード」の部分を「集約されたビルド」から「個々のビルド」に変更しよう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/66e03b83-40d0-1a61-1612-35de27667014.png)

これで再度マージリクエストを作成して動作させてみると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/ea8c65a3-62e7-b830-8129-51a8c25341b5.png)

ビルド結果が書き戻された！

今度こそ、これで、簡単にAWS CodeBuildのCIの恩恵に預かることができるようになった！

:::note
なお、本記事を執筆した2024/8/3時点では、上記のバッチレポートモードはTerraformに対応していないため、マネージメントコンソールから手動で変更をしている。
:::