ぶちのブログ

競プロとCTFが趣味なWebエンジニアのアウトプットの場

Fargateでwebサーバをデプロイする時にハマりやすい罠の個人的まとめ

はじめに

Fargateでwebサーバをデプロイする際に、いっつも同じようなことでハマっているので、備忘としてまとめておきます。
あわよくば、ハマる前に皆様を救えればと願ってこの記事を書いています。

CloudWatchにlog groupを作成していない、log group名が間違っている

タスクの実行時にlog group名を渡す必要がありますが、明示的に引数を渡さない場合にはECSからは勝手に作成はしてくれません。(-create-log-groupsという引数が必要)
そのため、log groupを作成していない場合や、log group名を間違えている場合には、タスク自体が立ち上がりません。

当然log groupにはログも出ないので、慣れていないと特定が難しいです。

role周りで不十分な権限がある

ここはまず用語の整理が難しいです。

taskExecutionRoleはタスクを実行するための権限で、CloudWatchへの書き込み、ECRへの読み込み等の権限が必要になります。
AWSのプリセットにある、AmazonECSTaskExecutionRolePolicyというpolicyを元にロールを作成すればよいでしょう。

taskRoleは、タスクを実行する際にサーバに与える権限で、アプリにもよりますが、例えばS3やSESなどのアクセスの権限を与えます。(EC2に与えるロールと同じ雰囲気です)
taskRoleには信頼されたエンティティとして、ecs-tasksを指定する必要があります。

LoadBalancerのtarget groupのtypeがIPになっていない

LoadBalancerのtypeをデフォルトのinstanceで作ってしまうとtarget groupにタスクを登録することができません。
後から変更することはできないため、ちゃんとtypeをIPにして作成しましょう。

healthcheckが通っていない

タスク自体は起動しているけれどタスクが死に続けている場合があります。
基本的にはタスクのログを見るとよいのですが、エラーログが出ずにサーバが終了している場合があります。

その場合はhealthcheckが通らずに、LoadBalancerによってシグナルを送られて終了している可能性があります。 (Railsのサーバの場合は、gracefully stoppingのログが出ます)

まずはportやpath、またはsecurity groupの設定を見直します。
webサーバのsecurity groupに、LoadBalancerからのアクセスを許可する設定を書く必要があります。

またhealthcheckの間隔や回数を少なくしすぎると、サーバが立ち上がる前にhealthcheckに失敗した扱いになってしまう場合があります。
その場合には、healthcheckの設定を変更するか、target groupのDeregistration delayやSlow start durationの設定を変更すると上手くいくかと思います。