TerraformでCodeBuildのレポート機能を使ってみる


はじめに

昨年5月に CodeBuild のレポート機能が追加されたが、自分の所属するプロジェクトでは自動テストやカバレッジのレポートは既に別のソリューションを導入していたのであまり触っていなかった。
今回、別の記事を書くにあたり、この辺りの機能を試してみたくなったので、併せて使ってみた。

なお、本記事の前提知識として、

  • CodeBuild のプロジェクトを IaC で書いたことがある
  • CodeBuild のレポート機能の概要を知っている

ことが前提となる。
※CodeBuild のレポート機能の概要は例によってクラスメソッド先生が分かりやすい

必要な Terraform リソース

必要なリソースは、aws_codebuild_report_group だ。
テストレポートとカバレッジレポートで出力が違うため、type プロパティで指定ができる。

一癖あるのが name プロパティで、AWS公式ドキュメントによると、

「CodeBuildのプロジェクト名」-「Buildspec の reports セクションで指定するグループ名」

という名前が適用されるらしい(変更できるかはよく分からない)。
そんな感じなので、以下のように定義する。

################################################################################
# S3                                                                           #
################################################################################
resource "aws_s3_bucket" "test" {
  bucket        = local.s3_testreport_bucket_name
  acl           = "private"
}

resource "aws_s3_bucket" "coverage" {
  bucket        = local.s3_coveragereport_bucket_name
  acl           = "private"
}

################################################################################
# CodeBuild                                                                    #
################################################################################
resource "aws_codebuild_report_group" "test" {
  name = "${local.codebuild_project_name}-${local.codebuild_test_reportgroup_name}"
  type = "TEST"

  export_config {
    type = "S3"

    s3_destination {
      bucket              = aws_s3_bucket.test.id
      encryption_disabled = false
      encryption_key      = data.aws_kms_key.aws_s3.arn
    }
  }
}

resource "aws_codebuild_report_group" "code_coverage" {
  name = "${local.codebuild_project_name}-${local.codebuild_codecoverage_reportgroup_name}"
  type = "CODE_COVERAGE"

  export_config {
    type = "S3"

    s3_destination {
      bucket              = aws_s3_bucket.coverage.id
      encryption_disabled = false
      encryption_key      = data.aws_kms_key.aws_s3.arn
    }
  }
}

そんなに難しいことはないが、公式ドキュメントによると、

Note: the API does not currently allow setting encryption as disabled

とのことで、encryption_disabled が無効にできないんだとか。

ということは、KMS が必要になるが、ここは別に AWS マネージドな KMS でも良いので、お手軽にやるなら

data "aws_kms_key" "aws_s3" {
  key_id = "alias/aws/s3"
}

な感じで S3 バケット用のエイリアスを引っ張ってきて設定しよう。
当然ながら、S3 バケットに PutObject をするための権限を CodeBuild のサービスロールに付与するのを忘れないように。

ちなみに、export_configNO_EXPORT を指定することも可能だが、エラーが出たときにプレーンなファイルが残っていないと調査が困難なので、最初は出力しておくのがオススメ。

Buildspec での指定

レポートを出力するには、出力形式に合わせたフォーマットで Buildspec 上でファイルを渡してあげなければいけない。
テストとカバレッジであれば以下ように両方を指定する。

reports:
  ${TEST_REPORTGROUP_NAME}:
    files:
      - "report/report.xml"
    file-format: "JUNITXML"
  ${COVERAGE_REPORTGROUP_NAME}:
    files:
      - "report/coverage.xml"
    file-format: "COBERTURAXML"

環境変数になっている部分が、グループ名だ。
↑で作ったグループ名の書き換え忘れがないように、CodeBuild の環境変数で渡すようにしている。

################################################################################
# CodeBuild                                                                    #
################################################################################
resource "aws_codebuild_project" "test" {
  (中略)
  environment {
    environment_variable {
      name  = "TEST_REPORTGROUP_NAME"
      value = local.codebuild_test_reportgroup_name
    }
    environment_variable {
      name  = "COVERAGE_REPORTGROUP_NAME"
      value = local.codebuild_codecoverage_reportgroup_name
    }
  }
  (後略)

実際に出力するファイルの形式については、言語によっても異なるので、それぞれの言語に合わせて対応してもらいたい。
詳細は AWS の公式ドキュメントに書かれている。

いざ、動かす!

さて、これで CodeBuild を実行すれば、レポートのタブから以下のように結果が確認できるようになる。

さらに、ここからレポートに飛ぶことで、以下のようにテストとカバレッジのレポートを確認できる。

テストレポート


また、グループのトップに行けば、エラーの推移等も確認可能だ。

カバレッジレポート

こちらもグループのトップから推移の確認が可能。

余談

ちなみに、レポートグループにレポートが残っていると、aws_codebuild_report_groupdestroy 時に

 InvalidInputException: Report group could only be deleted after its reports are deleted

なエラーが出て消せない。S3バケットの force_destroy プロパティみたいなものが出てほしい……。
※実運用上ではこのリソースを消すことはあまりなさそうなので、実質問題ないとは思うが。