CodeBuild で Buildx を使ってクロスプラットフォームビルドを行う
AWS Fargate が Graviton2 に対応しました
AWS Fargate が Graviton2 に対応しました。
CodeBuild でクロスプラットフォームビルドを行い、ARM プロセッサで Fargate タスクを動かします。
CodeBuild で Buildx を利用する
既に CodeBuild は Graviton2 に対応しています。
そのため、Graviton2 の CodeBuild でイメージをビルドし、Graviton2 対応の Fargate で動作させることは簡単です。
しかし、同じイメージを Fargate で Graviton2 が利用できないリージョンでも動かしたかったため、アーキテクチャ毎にビルド用の CodeBuild を用意するのもナンセンスに感じました。
そのため、x86_64 の CodeBuild で x86_64 向けと arm64 向けのイメージをビルドすることにしました。ところが、残念ながら CodeBuild は現時点では Buildx をサポートしていません。
これに対応するため、install フェーズで最新の buildx をインストールしています。
また、ECR は Docker マニフェストリストの作成・プッシュによるマルチアーキテクチャイメージに対応しています。
これにより、同じイメージ名、イメージタグで複数のアーキテクチャの一意なイメージを取り扱うことができます。
下記にサンプルの buildspec.yml を示します。
phases:
install:
commands:
# CodeBuild does not support Docker Buildx.
# SEE ALSO: https://github.com/aws/aws-codebuild-docker-images/pull/379
- BUILDX_BINARY_URL=$(curl -sLo - https://api.github.com/repos/docker/buildx/releases/latest | jq '.assets[] | select(.browser_download_url | contains("linux-amd64")).browser_download_url' -r)
- mkdir -p ~/.docker/cli-plugins
- curl -sL $BUILDX_BINARY_URL -o ~/.docker/cli-plugins/docker-buildx
- chmod +x ~/.docker/cli-plugins/docker-buildx
- docker run --privileged --rm tonistiigi/binfmt --install amd64,arm64
pre_build:
commands:
- COMMIT_ID=${CODEBUILD_RESOLVED_SOURCE_VERSION:0:8}
- AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
- REGISTRY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
- IMAGE_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE_NAME:$COMMIT_ID
build:
commands:
- |
for arch in amd64 arm64; do
docker buildx build . -t $IMAGE_URI-$arch --platform linux/$arch --load
done
post_build:
commands:
- aws ecr get-login-password | docker login --username AWS --password-stdin $REGISTRY_URI
- |
for arch in amd64 arm64; do
docker push $IMAGE_URI-$arch
done
# Pushing a multi-architecture image.
# SEE ALSO: https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-multi-architecture-image.html
- docker manifest create $IMAGE_URI $IMAGE_URI-amd64 $IMAGE_URI-arm64
- |
for arch in amd64 arm64; do
docker manifest annotate $IMAGE_URI $IMAGE_URI-$arch --arch $arch
done
- docker manifest push $IMAGE_URI
- printf '[{"name":"IMAGE_URI","imageUri":"$IMAGE_URI"}]' | envsubst | tee imagedefinitions.json
- printf '{"ImageURI":"$IMAGE_URI"}' | envsubst | tee imageDetail.json
その他の注意点
タスク定義ファイルを AWS CLI で aws ecs register-task-definition
する場合、AWS CLI v1 は runtimePlatform
属性に対応していません。
CodeBuild の al2/standard/3.0
を使用している場合、現時点では AWS CLI v1 なので注意しましょう。
"runtimePlatform": { "cpuArchitecture": "ARM64" },
Discussion