LoginSignup
1
1

AWS CodePipeline V2のトリガーフィルターをTerraformで扱う

Posted at

はじめに

2023年10月24日に発表されたAWS CodePipelineのV2タイプに対して2024年2月9日にもトリガーフィルターの新機能が追加された。これにより、GitHubやGitLab(セルフマネージド含む)のソースプロバイダに対して、

  • リポジトリへのPush契機だけではなく、プルリクエスト発行契機でも作成が可能になる
    ⇒ プルリク時にテストだけ流してパスしたことを確認してからマージすることが容易になる
  • ファイルパスで対象ファイルをフィルタすることが可能になる
    ⇒ モノレポで構成されるプロジェクトの特定領域の更新時だけビルドをすることが容易になる

といったことができるようになり、より柔軟にパイプラインが構成できるようになった。

TerraformのAWS Providerも追従してトリガーフィルターが利用可能になっているため、今回は、プルリクエストのフィルタをIaCで作成してみる。

本記事の前提となる知識は、主に以下だ。

  • TerraformでAWS CodePipelineを実装したことがある

なお、TerraformのAWS CodePipelineの実装サンプルそのものは過去の記事で書いているので、実装経験のない人は参考にしていただきたい。

トリガーフィルターは、AWS CodePipelineのソースプロバイダがAWS CodeCommitの場合は利用できない。AWS本家のマネージドサービスなのになぜ……という気はするが、ひとまず、外部のソースプロバイダを設定するにはAWS CodeStar Connections改めAWS CodeConnectionsを設定する必要がある。
AWS CodeConnectionを外部のプロバイダに設定する方法は、こちらの記事に記載しているので、この設定が済んでいる前提で以降の説明を記載する。

Terraformでのトリガーフィルター設定方法

パイプラインは以下のように設定をする。
なお、今回は、以下の設定を事前に行っている。

プロバイダ GitLabセルフマネージド
グループ example_group
リポジトリ example_repository
マージ先のブランチ main
resource "aws_codepipeline" "example" {
  name     = local.codepipeline_pipeline_name
  role_arn = aws_iam_role.codepipeline.arn

+  pipeline_type = "V2"

+  trigger {
+    provider_type = "CodeStarSourceConnection"
+    git_configuration {
+      source_action_name = "Source"
+      pull_request {
+        events = ["OPEN"]
+        branches {
+          includes = ["main"]
+        }
+      }
+    }
+  }

  artifact_store {
    type     = "S3"
    location = aws_s3_bucket.example.bucket
  }

  stage {
    name = "Source"

    action {
      run_order        = 1
      name             = "Source"
      category         = "Source"
      owner            = "AWS"
      provider         = "CodeStarSourceConnection"
      version          = "1"
      output_artifacts = ["SourceArtifact"]
      namespace        = "SourceVariables"

      configuration = {
        ConnectionArn    = aws_codestarconnections_connection.example.arn
        FullRepositoryId = "example_group/example_repository"
        BranchName       = "main"
      }
    }
  }

  stage {
    name = "Build"

    action {
      run_order       = 2
      name            = "Build"
      category        = "Build"
      owner           = "AWS"
      provider        = "CodeBuild"
      version         = "1"
      input_artifacts = ["SourceArtifact"]

      configuration = {
        ProjectName = aws_codebuild_project.example.name
      }
    }
  }
}

詳細なトリガーフィルターの仕様は、AWS公式のAWS CodePipelineユーザーガイドTerraformドキュメントのtriggerブロックの項を参照。

プルリクエストは、events属性で指定し、OPEN, UPDATE, CLOSEの契機でパイプラインを起動することができる。配列なので、OPEN, UPDATE両方を指定しておき、プルリクエストで差し戻しになった後に更新した場合に、再度パイプラインをトリガすることも可能だ。

その他、Pushのフィルタについては、ファイルパス以外にtagsを指定することでタグでフィルタすることもできる。

ファイルパス、タグ、ブランチ名にはワイルドカードも使えるので、例えば、ブランチ指定でFeature/*とすることで、Featureブランチすべてを対象にパイプラインを実行することも可能になる。

AWS CodeBuildでGitLabのメタ情報を参照する方法

さて、AWS CodeBuildでは、予約された環境変数を使うことで様々なメタ情報を取得することができる。
せっかくGitLabのプルリクエストが扱えるようになったのだから、GitLabのプルリクエスト関連のAPIを実行して、GitLab側にビルド結果を書き込むことで、マージまでの流れにおける開発者体験が向上するだろう。

ということで、環境変数にどのような情報が設定されるか、以下のようにBuildspecを作成して確認してみよう。

buildspec.yml
version: 0.2

phases:
  build:
    commands:
      - env | grep CODEBUILD_

このBuildspecで実行したAWS Codebuildのログの抜粋は以下。

[Container] 2024/03/31 11:55:22.932147 Running command env | grep CODEBUILD_
CODEBUILD_INITIATOR=codepipeline/example-pipeline
CODEBUILD_SRC_DIR=/codebuild/output/srcXXXXXXXXXX/src
CODEBUILD_BUILD_IMAGE=aws/codebuild/amazonlinux2-x86_64-standard:5.0
CODEBUILD_KMS_KEY_ID=arn:aws:kms:ap-northeast-1:XXXXXXXXXXXX:alias/aws/s3
CODEBUILD_GOPATH=/codebuild/output/srcXXXXXXXXXX
CODEBUILD_ACTION_RUNNER_URL=https://codefactory-ap-northeast-1-prod-default-build-agent-executor.s3.ap-northeast-1.amazonaws.com/cawsrunner.zip
CODEBUILD_PROJECT_UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
CODEBUILD_BUILD_ID=example-buildproject:fcd5d542-XXXX-XXXX-XXXX-XXXXXXXXXXXX
CODEBUILD_CI=true
CODEBUILD_RESOLVED_SOURCE_VERSION=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
CODEBUILD_AGENT_ENDPOINT=http://127.0.0.1:7831
CODEBUILD_LAST_EXIT=0
CODEBUILD_BUILD_ARN=arn:aws:codebuild:ap-northeast-1:XXXXXXXXXXXX:build/example-buildproject:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
CODEBUILD_BUILD_NUMBER=6
CODEBUILD_LOG_PATH=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
CODEBUILD_EXECUTION_ROLE_BUILD=true
CODEBUILD_SOURCE_VERSION=arn:aws:s3:::example-bucket/example-codepipelin/SourceArti/XXXXXXX
CODEBUILD_BUILD_URL=https://ap-northeast-1.console.aws.amazon.com/codebuild/home?region=ap-northeast-1#/builds/example-buildproject:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/view/new
CODEBUILD_FE_REPORT_ENDPOINT=https://codebuild.ap-northeast-1.amazonaws.com/
CODEBUILD_BUILD_SUCCEEDING=1
CODEBUILD_BMR_URL=https://CODEBUILD_AGENT:3000
CODEBUILD_AUTH_TOKEN=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
CODEBUILD_CONTAINER_NAME=default
CODEBUILD_START_TIME=1711886110515

……なんと、欲しい情報が無い!これではやりたいことが実現できないではないか!

と思ってマネコンを探して、

キャプチャ1.png

ここから……

image.png

見つけた!

ソースステージの出力に入っているということは、AWS CodePipelineの変数を使えばパイプラインの他のステージでも取得ができる!

ということで、以下のようにTerraformのコードを見直そう。あるステージの出力を後方のステージで参照する場合、namespaceの設定をしないと取得できないということに気を付けよう。

################################################################################
# CodePipeline                                                                 #
################################################################################
resource "aws_codepipeline" "example" {
  name     = local.codepipeline_pipeline_name
  role_arn = aws_iam_role.codepipeline.arn

  pipeline_type = "V2"

  trigger {
    provider_type = "CodeStarSourceConnection"
    git_configuration {
      source_action_name = "Source"
      pull_request {
        events = ["OPEN"]
        branches {
          includes = ["main"]
        }
      }
    }
  }

  artifact_store {
    type     = "S3"
    location = aws_s3_bucket.example.bucket
  }

  stage {
    name = "Source"

    action {
      run_order        = 1
      name             = "Source"
      category         = "Source"
      owner            = "AWS"
      provider         = "CodeStarSourceConnection"
      version          = "1"
      output_artifacts = ["SourceArtifact"]
+     namespace        = "SourceVariables"

      configuration = {
        ConnectionArn    = aws_codestarconnections_connection.example.arn
        FullRepositoryId = "root/test"
        BranchName       = "main"
      }
    }
  }

  stage {
    name = "Build"

    action {
      run_order       = 2
      name            = "Build"
      category        = "Build"
      owner           = "AWS"
      provider        = "CodeBuild"
      version         = "1"
      input_artifacts = ["SourceArtifact"]

      configuration = {
        ProjectName = aws_codebuild_project.example.name
+       EnvironmentVariables =  jsonencode([
+         {
+           type  = "PLAINTEXT"
+           name  = "CODEPIPELINE_SRCVAR_COMMITID"
+           value = "#{SourceVariables.CommitId}"
+         },
+         {
+           type  = "PLAINTEXT"
+           name  = "CODEPIPELINE_SRCVAR_FULLREPOSITORYNAME"
+           value = "#{SourceVariables.FullRepositoryName}"
+         },
+         {
+           type  = "PLAINTEXT"
+           name  = "CODEPIPELINE_SRCVAR_PULLREQUESTID"
+           value = "#{SourceVariables.PullRequestId}"
+         },
+         {
+           type  = "PLAINTEXT"
+           name  = "CODEPIPELINE_SRCVAR_PULLREQUESTTITLE"
+           value = "#{SourceVariables.PullRequestTitle}"
+         },
+       ])
      }
    }
  }
}

これで、Buildspecを以下のように見直す。

buildspec.yml
version: 0.2

phases:
  build:
    commands:
-      - env | grep CODEBUILD_
+      - env | grep CODEPIPELINE_SRCVAR

AWS CodeBuildのログを取得すると、

[Container] 2024/03/31 12:25:27.225154 Running command env | grep CODEPIPELINE_SRCVAR
CODEPIPELINE_SRCVAR_PULLREQUESTID=12
CODEPIPELINE_SRCVAR_PULLREQUESTTITLE=Feature/test3
CODEPIPELINE_SRCVAR_COMMITID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
CODEPIPELINE_SRCVAR_FULLREPOSITORYNAME=example_group/example_repository

取れた!これで、AWS CodeBuildからもGitLabのAPIを実行して情報を書きこむことができるようになった!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1