😸

CodeBuildでDockerイメージのタグにGitのタグ名を追加した

2024/12/05に公開

やりたいこと

AWS CodeBuildでECRにイメージをpushする際、latestタグとは別にGitのタグをイメージタグとしてpushしたい。

現状のデプロイパイプライン構成

AWS CodePipelineを用いて実装しています。

  • Source
    • GitHub
  • Build
    • AWS CodeBuild

CodeBuildの環境変数から取得してみる

https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html

CodeBuildにはデフォルトで環境変数が用意されていたので、それっぽいものを確認してみます。
buildspecのpre_build内で出力してみます。

phases:
  pre_build:
    on-failure: ABORT
    commands:
      # 省略
      - echo $CODEBUILD_WEBHOOK_TRIGGER
      - echo $CODEBUILD_WEBHOOK_HEAD_REF
      - echo $CODEBUILD_SOURCE_VERSION
      - echo $CODEBUILD_RESOLVED_SOURCE_VERSION

CODEBUILD_RESOLVED_SOURCE_VERSION
=> 出力なし
CODEBUILD_WEBHOOK_TRIGGER
=> 出力なし
CODEBUILD_WEBHOOK_HEAD_REF
=> arn:aws:s3:::codepipeline-ap-northeast-1-xxxxxxx/pipel/SourceArti/xxxxxx
CODEBUILD_SOURCE_VERSION
=> f6fxxxxxxxxxxxxxxxxxxxxxxxxxx(コミットID)

取れなさそうだったので別の方法を検討してみます。

gitコマンドで取得してみる

gitコマンドでタグの出力を試みます。
上記同様buildspecで試してみます。

- echo $(git describe --tags)
[Container] 2024/12/03 09:27:36.458658 Running command echo $(git describe --tags)
fatal: not a git repository (or any parent up to mount point /codebuild)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

.gitディレクトリへのアクセス権がなかったりするとこのエラーが起こるとのこと。
追加で調べてみるとどうやら.gitディレクトリ自体が存在しておらず、CodePipelineのSourceアクションの出力形式が問題みたいでした。

出力形式はCloudFormationではOutputArtifactFormatに該当します。

# codepipeline
Type: 'AWS::CodePipeline::Pipeline'
Properties:
  Stages:
    - Name: Source
      Actions:
        - Name: Source
          Namespace: SourceVariables
          ActionTypeId:
            Category: Source
            Owner: AWS
            Version: '1'
            Provider: CodeStarSourceConnection
          OutputArtifacts:
            - Name: SourceArtifact
          Configuration:
            BranchName: master
            # CODE_ZIPからCODEBUILD_CLONE_REFに変更
            OutputArtifactFormat: CODEBUILD_CLONE_REF
            # 省略

権限エラーになったので、下記参考にcodestar-connections:UseConnectionの権限を追加しました。
https://docs.aws.amazon.com/codepipeline/latest/userguide/tutorials-github-gitclone.html#tutorials-github-gitclone-rolepolicy

  CodePipelineRole:
    Type: AWS::IAM::Role
    Properties:
      Policies:
        - PolicyName: test-codepipeline-policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Resource: '*'
                Action:
                  - codestar-connections:UseConnection

最終的なbuildspec.ymlはこちらです。

# buildspec.yaml
phases:
  pre_build:
    on-failure: ABORT
    commands:
      - IMAGE_TAG=$(git describe --tags)
  build:
    on-failure: ABORT
    commands:
      - docker build .
        -t $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$ECR_REPOSITORY:$IMAGE_TAG
        -t $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$ECR_REPOSITORY:latest

  post_build:
    on-failure: ABORT
    commands:
      - docker push $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$ECR_REPOSITORY:latest
      - docker push $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$ECR_REPOSITORY:$IMAGE_TAG

docker push -aで複数タグをまとめてpushできるみたいです。

- docker push $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$ECR_REPOSITORY -a

ECRにタグ付けされたイメージが無事アップロードされていました!

Discussion