📝

ECSのハンズオンでハマったら中の人が助けてくれた

2021/07/06に公開

現在AWS DVAに挑戦するために、ECSの勉強をしており、ハンズオンをやっています。
先日以下のハンズオンでハマったので解決法を紹介します。
Amazon ECS マイクロサービスCI/CDハンズオン
※資料は更新される可能性があるため、本記事の内容は参考程度に留めて頂ければ幸いです。

結論

buildspec.ymlの

$(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <Account ID>.dkr.ecr.ap-northeast-1.amazonaws.com

に書き換えます。

変更理由

AWS CLIのバージョンの差異です。
ecr get-loginはv2では使用できず、コマンド実行時に以下のエラーとなりました。

[Container] 2021/07/06 02:07:34 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email). Reason: exit status 252

経緯

資料のbuildspec.ymlをそのまま使用する

最初は資料のp.141に従い、buildspec.ymlのREPOSITORY_URIを、作成したECRのリポジトリURIに書き換えました。

buildspec.yml
version: 0.2
phases:
  pre_build:
    commands:
      - $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
      - REPOSITORY_URI=<Account ID>.dkr.ecr.us-east-1.amazonaws.com/php-sample
      - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)

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

  post_build:
    commands:
      - 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

ビルドプロジェクト作成

資料p.150のビルドプロジェクト作成時に、資料では以下の設定になっています。

- イメージ: aws/codebuild/standard:1.0
- イメージのバージョン: aws/codebuild/standard: 1.0-1.8.

しかし、実際に選択できるイメージは以下の2つでした。

  • aws/codebuild/standard:4.0
  • aws/codebuild/standard:5.0

イメージのバージョンでは
このランタイムバージョンには常に最新のイメージを使用してください
と表示されているので、最新バージョンを選択しました。
また、「環境タイプ」も資料に記載がなかったので、デフォルトの「Linux」のままとしました。

おそらく、このランタイムバージョンがAWS CLIのバージョンの差の原因かなと推測しています。

Buildでエラー

資料p.160の「変更をリリースする」を実行したところ、CodeBuildで以下のエラーが発生しました。

[Container] 2021/07/06 02:07:34 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email). Reason: exit status 252

調べてみると、CLI v2ではecr get-loginコマンドが使えないとのことでした。
詳しくは以下の記事をご覧ください。
[アップデート]AWS CLI v2 で $ aws ecr get-login を使うときの注意点 | DevelopersIO

buildspec.ymlのコマンドを修正

ecr get-loginコマンドが使用できないことが分かったので、buildspec.ymlの対象コマンド部分を

$(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)

から

$(aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <Account ID>.dkr.ecr.ap-northeast-1.amazonaws.com)

に書き換えました。

再挑戦

変更をCodeCommitにpushすることで、CodePipelineが動き出し、再度Buildまで来ましたが、今度は以下のエラーが発生しました。

/codebuild/output/tmp/script.sh: 4: Login: not found

原因が分からず迷走していたので、上記をツイッターに投げたところ、なんとAWSの中の方からメッセージが飛んできました!

おそらく buildspec.yml に書かれたコマンドの実行時に失敗しているのかなと推察しますが、試しに
aws ecr ... ap-northeast-1.amazonaws.com
コマンド全体を囲っている $() を外してみていただけますか?

ありがとうございます!!(泣)
早速以下のようにコマンドを書き換えて実行したところ、無事ビルドが通りました。

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <Account ID>.dkr.ecr.ap-northeast-1.amazonaws.com

一発で解決するあたり、さすが中の人!!

そして、この資料を作成した方にもご連絡頂いたようで、その方からも

この PDF を AWS Dev Day で公開したのが約 2 年前でPDFの方をメンテしていないのですが、WEBでできるコンテンツの方は適宜手直しをしています。
少しお時間いただきますが、今回のCLI v2仕様に変えて、URLをお伝えしますね!

とのご返答を頂きました。
なんという神対応!!
本当にありがとうございます!

まとめ

今回はECSのハンズオンでハマった体験と解決法を紹介しました。
思わぬエラーでハマりましたが、中の人に助けて頂いたおかげで無事解決できました。
今回紹介したハンズオンはECSやCodeシリーズについて手を動かして学ぶにはすごくよい資料だと思いますので、ぜひやってみてください!
繰り返しになりますが、Amazon ECS マイクロサービスCI/CDハンズオンの記事は更新される可能性があるため、本記事も参考程度にご覧頂ければ幸いです。

Discussion