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