CodePipelineから別アカウントの CodeCommitとECRを利用する

CodePipelineから別アカウントの CodeCommitとECRの2つを利用する手順と躓いたところを書きます。

主には別アカウントにECRを配置するところで躓いたので、そこを中心に書きます。

下記の図は書いていませんが、検証環境アカウントで動作確認をしたECR内のイメージを本番環境アカウントで利用したいため、Dev環境にECRを置く構成としました。

 

以下、イメージ図です。

前提

・同一アカウント(検証環境)で上記の構成を構築済(CodeCommit、ECRは検証環境にある状態)

・buildspec.ymlでSpringbootのjarファイルをコンパイルして、ECRにイメージプッシュ

 ※他の言語でも本編に影響しないが念のため記載

 

Code CommitをDev環境に配置する(前半)

Dev環境:Code Commit

検証環境:Code Commit以外のサービス

 

以下のクラスメソッドさんの記事の手順で構築できます。

dev.classmethod.jp

Code Commitは他のサイトでもいろいろ紹介されていたのですが、上記サイトが一番分かりやすく、しかも手順もしっかり書かれていました。

 

ECRをDev環境に配置する(後半)

Dev環境(AWSアカウント 111111111111)

 :Code Commit、ECR(今回の手順はここ)

検証環境(AWSアカウント 222222222222)

 :上記以外のサービス

概要

 Dev環境

  1、ECRを作成し、リポジトリポリシーを設定(検証環境からアクセスを許可)

  2、CodeBuild用のIAMロールを作成

   (検証環境アカウントのIAMロールからAssumeRoleされる)

 検証環境

  3、CodeBuild用のIAMロールを作成

   (2のIAMロールをAssumeRoleする)

 Dev環境

  4、buildspec.ymlファイル修正(主にECRにログインするところを修正)

 

1~3はすんなりできるのですが、4のところで躓きました。

 

手順詳細

Dev環境

1、ECRを作成し、リポジトリポリシーを設定(検証環境からアクセスを許可)

 1-1、ECRを作成

   任意のリポジトリ名を設定し、「リポジトリ作成」ボタンをクリック

   ※他はデフォルトでOK(検証環境なので)

 

 1-2、ECRリポジトリポリシーを設定

  対象のECRを選択し、「アクション ⇒ 許可」をクリック

 

  「ポリシーJSONの編集」をクリック

 

 以下をポリシーJSONに入力する

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCrossPushPull",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::222222222222:root"
      },
      "Action": [
        "ecr:BatchCheckLayerAvailability",
        "ecr:BatchGetImage",
        "ecr:CompleteLayerUpload",
        "ecr:GetDownloadUrlForLayer",
        "ecr:InitiateLayerUpload",
        "ecr:PutImage",
        "ecr:UploadLayerPart"
      ]
    }
  ]
}

「"AWS": "arn:aws:iam::222222222222:root"」は、以下のように手順3で作成する検証環境のCodeBuild用のIAMロールにした方が良いです。

「"AWS": "arn:aws:iam::222222222222:role/検証環境のCodeBuild用のIAMロール名"」

 

2、CodeBuild用のIAMロールを作成

 2-1、ポリシーを作成(ポリシー名:codebuild-policy-111111111111)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ECRAccessPolicy",
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:GetRepositoryPolicy",
                "ecr:DescribeRepositories",
                "ecr:ListImages",
                "ecr:DescribeImages",
                "ecr:BatchGetImage",
                "ecr:GetLifecyclePolicy",
                "ecr:GetLifecyclePolicyPreview",
                "ecr:ListTagsForResource",
                "ecr:DescribeImageScanFindings",
                "ecr:InitiateLayerUpload",
                "ecr:UploadLayerPart",
                "ecr:CompleteLayerUpload",
                "ecr:PutImage"
            ],
            "Resource": "*"
        }
    ]
}

 2-2、IAMロールを作成(IAMロール名:codebuild-role-111111111111)

  2-1で作成したポリシーを付ける

 

 信用されたエンティティを入力する

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::222222222222:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

※ロール作成時には自由に入力できないため、一旦仮の値を設定しロールを作成し、編集にて入力

 

 

検証環境

3、CodeBuild用のIAMロールを作成

 3-1、ポリシーを作成(ポリシー名:codebuild-policy-222222222222)

  手順2-2で作成したDev側のロールをResourceに指定する

 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::111111111111:role/codebuild-role-111111111111"
        }
    ]
}

 3-2、IAMロールを作成(IAMロール名:codebuild-role-222222222222)

  3-1で作成したポリシーを付ける

   ※画像は省略

 

  信用されたエンティティを入力する

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "codebuild.amazonaws.com",
                "AWS": "arn:aws:iam::111111111111:root",
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

Dev環境

4、buildspec.ymlファイル修正

権限も設定したのでECRのURLだけ変更すればうまくプッシュできるのでは?を思ったのですが、ECRのログインができず修正する必要があります。

いろいろ方法あるのですが、codebuild内にAWSのプロファイルを作成しました。

赤字が修正した箇所になります

 

version: 0.2
phases:
  install:
    runtime-versions:
      python: 3.9
  pre_build:
    commands:
      - echo "[profile aaa111]" > .awscli-config
      - echo "role_arn = arn:aws:iam::111111111111:role/codebuild-role-111111111111" >> .awscli-config
      - echo "credential_source = EcsContainer" >> .awscli-config
      - export AWS_CONFIG_FILE=${CODEBUILD_SRC_DIR}/.awscli-config
      - $(aws --profile aaa111 ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
      - REPOSITORY_URI=111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/cross-ecr
      - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)

  build:
    commands:
      - mvn clean
      - mvn install
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG

  post_build:
    commands:
      - mvn package
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - printf '{"Version":"1.0","ImageURI":"%s"}' $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json

artifacts:
    files: imageDetail.json

 

以上で設定は完了です。

 

以下は気になったことや躓いたところです

「4、buildspec.ymlファイル修正」で気になったこと

①CodeBuildのどのフォルダで実行されているのか?

「/codebuild/output/src945596495/src」でした。

※「src945596495」は実行するごとに変わります。(たぶん)

②「.awscli-config」の中身はどうなっているのか?

[profile aaa111]
role_arn = arn:aws:iam::111111111111:role/codebuild-role-111111111111
credential_source = EcsContainer

上記の内容のファイルをCode Commit内に用意し、ビルド時にコピーするのもありかな?と思います。

「[profile aaa111]」のprofileを付けないとエラーになります。

③「export」の「=」の前後に空白を入れない

「=」の前後に半角スペースがあったためエラーとなり30分ぐらいあたふたしました。

「export AWS_CONFIG_FILE = ${CODEBUILD_SRC_DIR}/.awscli-config」

AWS関係なく初歩的なミスですね。。

 

【参考サイト】

他のAWSアカウントのECRリポジトリにPush/Pullする - Qiita

CodeBuildのビルド内でAssumeRole(クロスアカウントアクセス)する方法とハマった話 | DevelopersIO