ECS Web Application ハンズオンを試してみた

ECSを使ってDjangoのアプリケーションをデプロイできるようになるため、まず手始めにECS Web Application ハンズオンを触ってみました。

ハンズオン自体はDjangoではなくRuby on Railsかつ、先日から新規ユーザーは使用できなくなったCloud9を使用する前提でしたが、ローカル環境でもうまく出来ました。

私の環境で操作した時の注意点を交えて軽くポイントを記録しておきます。

権限周り

今回は作成したIAMユーザーに対してAdministratorAccessを付与しました。

本来は必要最小限の原則に則るべきでグループを作成した上、必要な権限のみを付与すべきだと思いますが、今回はまずECSを触ることが目的と考えたので手軽さを優先しました。

クラスターの作成

クラスターでは以下の内容を選びました。

  • AMI: Amazon Linux 2 (kernel 5.10) (ハンズオンがこちらだったので)
  • EC2 インスタンスタイプ: t2.micro (無料利用枠だったので)

ただ、後述しますがAmazon Linux 2 (arm64) を選んでいた方が良かったと思うのと、インスタンスタイプもハンズオンに合わせてt3.mediumにしておいた方が良かったのかな?と思いました。

また、以下のエラーが出ました。

クラスター ecs-handson-cluster の作成中にエラーが発生しました。

Resource handler returned message: "Error occurred during operation 'CreateCluster SDK error: Service Unavailable. Please try again later. (Service: AmazonECS; Status Code: 500; Error Code: ServerException; Request ID: リクエストID; Proxy: null)'." (RequestToken: リクエストトークン, HandlerErrorCode: GeneralServiceException)

このエラー自体は初めて作成するときが原因のようだったので、再実行するようにしたら作成できました(同じ手順を繰り返そうとすると確かダメだったため)。

AWS CLI

AWS CLIの最新バージョンのインストールまたは更新のCommand line installer - All users を参考にしてコマンドを実行しました。

インストール自体は詰まるポイントは特にありませんでした。

ECRへのPush

ECR自体にはプッシュコマンドが出力されるので、それをコピペしてターミナル上で実行するのみで手軽でした。

しかし、最初の実行時には以下のメッセージが出ました。

Partial credentials found in shared-credentials-file, missing: aws_secret_access_key Error: Cannot perform an interactive login from a non TTY device

AWS Access Key(とAWS Secret Access Key)が無いことが原因でした。

こちらも調べたところAWS的には非推奨ですが、アクセスキーを作成後にaws configureコマンドで貼り付けて登録後は実行できるようになりました。

M1 Macで作業していたことによるデプロイ失敗

ハンズオンはRubyのバージョン指定がFROM public.ecr.aws/docker/library/ruby:3.2.1となっています。

ただ、M1 Mac上でビルドしたイメージをpushするのでAmazon Linux 2 (kernel 5.10) (AMD環境)ではダメなようでした。

というのも、pushした後に失敗して以下のエラーが出ていたからです。

ecs-ec2-service のデプロイ中にエラーが発生しました Resource handler returned message: "Error occurred during operation 'ECS Deployment Circuit Breaker was triggered'." (RequestToken: トークン, HandlerErrorCode: GeneralServiceException)

詳しいログは出ていませんでしたが、この辺りの記事を参考にしてARM, AMD周りの問題と判断しました。

Resource handler returned message: ECS Deployment Circuit Breaker was triggered (HandlerErrorCode: GeneralServiceException)

CPUアーキテクチャ違いで永遠にECSのタスクを起動できなかった問題

そのため、対処法としてはFROM --platform=linux/amd64 public.ecr.aws/docker/library/ruby:3.2.1と書き換えて実行した所、成功するようになりました。

起動確認ができないことも

ECS on EC2 では1つのタスクの起動に30分くらいかかり、かつもう1つのタスクの起動が終わりきらないことがありました。

タスクの起動に時間がかかるのは、M1 MacでARM用のdocker imageをbuildしていたことが原因で、タスクの起動についてはTaskFailedToStart: RESOURCE:MEMORYのエラーが出ていたので、ハンズオンとは異なる設定(t2.micro) あたりが悪いのかな?と思っています。

前者は作り直すのがちょっと手間に考えてamd64の記述をDockerfileに追加しましたが、ARM64環境で作成した方が結果的に良かったのかな?とは思いました。

後者は公式によると以下内容が原因のようでした。

RESOURCE:MEMORY エラーの場合、タスクによって要求されたメモリの量がコンテナインスタンスで利用できません。これは通常、タスク定義のメモリ量要件が、キャパシティプロバイダーにマッピングされた Auto Scaling グループで定義される Amazon EC2 インスタンスでサポートされているメモリよりも大きい場合に発生します。キャパシティプロバイダーの設定を確認する必要があります。

Amazon ECS での API エラーの原因