1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS CodePipeline + CodeBuild で Submodule 付きのリポジトリをビルドする

Posted at

弊社では一部のサービスのビルドとデプロイにAWS CodePipeline, CodeBuild を使用しています。インフラの作成には terraform を使用しています。
ソースは Github で管理しているのですが、ビルドしたいリポジトリが別リポジトリをサブモジュールとして参照している場合に、サブモジュールのソースを取得できませんでした。
その時の対処法を記しておきます。

CodeBuild でサブモジュール使えなかったっけ?

使えます。ただし CodePipeline と組み合わせなければ。
terraform のリファレンスを見てみましょう。
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/codebuild_project

source: git_submodules_config

This block is only valid when the type is CODECOMMIT, GITHUB, GITHUB_ENTERPRISE, GITLAB, or GITLAB_SELF_MANAGED.

fetch_submodules - (Required) Whether to fetch Git submodules for the AWS CodeBuild build project.

CodePipeline と組み合わせているので type は CODEPIPELINE になっていました。ということで属性をちょっといじるだけでは解決しません。

対処法

パイプラインのソースステージでプライマリとサブモジュールそれぞれ別々に取得するよう action を作成します。ビルドステージではどれがプライマリなのかを示してやります。

terraform

まずは CodePipeline の定義

resource "aws_codepipeline" "pipeline" {
  # nameなどを省略
  
  stage {
    name = "Source"

    # プライマリリポジトリ用
    action {
      name             = "SourcePrimary"
      category         = "Source"
      namespace        = "SourceVariablesPrimary"
      owner            = "AWS"
      provider         = "CodeStarSourceConnection"
      version          = "1"
      output_artifacts = ["primary_output"]
        
      configuration = {
        ConnectionArn    = data.aws_codestarconnections_connection.github.arn
        FullRepositoryId = var.github_repository
        BranchName       = var.target_branch
      }
    }

    # サブモジュールリポジトリ用
    action {
      name             = "SourceSubModule"
      category         = "Source"
      namespace        = "SourceVariablesSubModule"
      owner            = "AWS"
      provider         = "CodeStarSourceConnection"
      version          = "1"
      output_artifacts = ["submodule_output"]
        
      configuration = {
        ConnectionArn    = data.aws_codestarconnections_connection.github.arn
        FullRepositoryId = var.github_repository_submodule
        BranchName       = var.target_branch_submodule
      }
    }
  }

  stage {
    name = "Build"

    action {
      name             = "Build"
      category         = "Build"
      owner            = "AWS"
      provider         = "CodeBuild"
      input_artifacts  = ["primary_output", "submodule_output"]
      output_artifacts = ["build_output"]
      version          = "1"

      configuration = {
        ProjectName   = aws_codebuild_project.buildstage.name
        # 2つ以上のソースがある時はどちらがプライマリか指定する必要がある
        PrimarySource = "primary_output"
      }
    }
  }
}

次に CodeBuild の定義です。

resource "aws_codebuild_project" "buildstage" {
  # nameなどを省略
  
  source {
    type      = "CODEPIPELINE"
    buildspec = "buildspec-build.yaml"
  }
}

buildspec.yaml

プライマリのリポジトリは自動でカレントディレクトリに展開されます。
一方、サブモジュールは環境変数 ${CODEBUILD_SRC_DIR_xxxxxxx} の示すディレクトリに展開されます。ここで xxxxxxx の部分はソースステージの action で指定した output_artifacts の値です。

セカンダリソースの場合、ディレクトリパスの環境変数は「CODEBUILD_SRC_DIR_」です。「」は作成するソース識別子です。

あとはサブモジュールのソースを任意のディレクトリに移動するなりしましょう。

version: 0.2

phases:
  pre_build:
    commands:
      # ソースステージの action で `output_artifacts = ["submodule_output"]` と指定したので
      # サブモジュールは ${CODEBUILD_SRC_DIR_submodule_output} に展開される
      cp -r ${CODEBUILD_SRC_DIR_submodule_output}/* ./submodule_directory/

まとめ

CodePipeline + CodeBuild でサブモジュールを含むソースをビルドする場合はこうするとよいです。

  • プライマリとサブモジュールをそれぞれソースのactionで別々に取得する
  • buildspec でサブモジュールを任意のディレクトリに移動する
1
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?