Amazon ECSでRailsサービスのコンテナを立ち上げた際、ELBのヘルスチェックが通らずTask failed ELB health checks in...と出た時の対処方法

## ECSでサービスが立ち上がらない！？

サービスを立てた際、こんな具合にタスクが起動しては落ちを繰り返しました。今回はそんな時の為のケーススタディを紹介します。

![Screenshot from 2022-04-07 09-46-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/14a9056f-7429-2e6d-4e1d-ea9b40aafe31.png)

## 原因究明1 CloudWatchのログを確認する

ECSの該当クラスター→タスクから現在実行中のタスクを選択肢、コンテナのタブを開くと、CloudWatchのログに遷移できます。

![Screenshot from 2022-04-07 09-50-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/e38243b6-2ce7-53c9-4f0f-377f62bc0b18.png)

### 原因究明1.1 CloudWatchにヘルスチェックのアクセスの痕跡がある　→　ターゲットグループのヘルスチェックの設定の問題

![Screenshot from 2022-04-07 09-54-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/ef01cc65-77b0-389f-58a2-fe1b9cee318d.png)

例えば、こんな具合にヘルスチェックのものと思われるアクセスが確認さた場合、単純にヘルスチェック側に問題が有ると思われます。

実際にヘルスチェックを見てみると…

![Screenshot from 2022-04-07 09-58-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/69a27ffe-b2c4-a608-def9-640ef1841261.png)

例えばこのケースだと、ヘルスチェックは`/`を呼びに行って`コード:200`が返っていることを期待していたのですが、ログを見ると`/login`にリダイレクトをかけて`コード:302`が返えしてしまっている為、ヘルスチェックに落ちて居る、といった具合になります。

### 原因究明1.2 Railsの立ち上げに失敗している（接続エラー）

エラーログをしっかり見ましょう。手元では上手く行くのに、DB(RDS)やRedisやElasticSearchといった物への接続エラーが発生している場合があります。

確認すべきは
- RDS等のVPCがECSと同じVPCに存在しているか
    - 別VPCでも複雑な設定をすれば接続は出来ますが、基本は同じVPCに置いておくことをオススメします
- RDS等に紐づくセキュリティグループのインバウンドルールに、ECSのサービスに紐づくセキュリティグループから該当ポートでのアクセス許可があるか
- エンドポイントのURLが正しいか
    - 例えば、RDSが読み込み専用インスタンスのエンドポイントになっていないか？など

ただ、この辺のエラーはコンテナが異常終了するので、`Task failed ELB health checks in (target-group arn:aws:elasticloadbalancing....`とはまた別のエラーになると思われます。

### 原因究明1.3 Railsのその他のエラー

基本は、ログをみて解読すればだいたいのことは分かると思われます。よくありがちなこととして

- 環境変数の設定のミス、抜け漏れ

をよくやらかすので、一度確認してみて下さい。

### 原因究明1.4 Railsが立ち上がる前にヘルスチェックが走ってしまっている

あれ？アクセスログにはヘルスチェックっぽいものがあるのだけど・・・！という場合、Railsのサービスが立ち上がる前にヘルスチェックをした結果、Unhealthy認定を食らってしまう可能性があります。

ECSのサービスを更新して、ヘルスチェックの猶予を伸ばしてあげてください。

![Screenshot from 2022-04-13 16-30-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/fb9db557-e267-a52f-0154-14f076d48c1e.png)



## 原因究明2 ネットワークの設定を見直す

CloudWatchのログすら出ていない場合。出口(サービス側)ではなく、次は入り口(ネットワーク)から見ていきます。

### 原因究明2.1 セキュリティグループ設定の目視確認

まずやるべきこととしては、目視で設定を確認してみましょう。

- ELB側のセキュリティグループのインバウンドルールが、ポートが80番or443番を任意のIPを許可しているか？
- ECS側のセキュリティグループのインバウンドルールが、適切なポートでELB側のセキュリティグループを許可しているか？
- ELB側、ECS側それぞれ、アウトバウンドルールが任意のIPで全てのプロトコルを許可しているか？(デフォルトから設定をいじっていないか？)

の3つをとりあえず確認してみて下さい。

### 原因究明2.2 VPC Reachability Analyzerを使った自動チェック

目視だと思わぬ設定ミスをしている可能性があります。自動で検証する便利なツールに「VPC Reachability Analyzer」というのがあるので使ってみて下さい。

その際に注意点なのですが、ECS側はタスクを立てては停止してを繰り返す為、毎度ネットワークインターフェイスが変わってしまい、適切な調査が出来ません。必ず、ECSのサービスの更新を行い**ヘルスチェックの猶予期間を長めに設定** してから行いましょう。

![Screenshot from 2022-04-07 11-06-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/1cb66274-1abe-e89c-ef3d-8c18ba7afe32.png)


VPC Reachability Analyzerの設定はこんな具合です。
![Screenshot from 2022-04-07 11-03-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/1476a756-3339-86b5-0f03-ad51aebed1ac.png)


画像では**空欄の送信元に利用しているELB側のセキュリティグループに紐づくネットワークインターフェイス** を選択して下さい。
**送信先には、ECS側のセキュリティグループが紐付いているネットワークインターフェイス** を選択して下さい。
**ポートにはターゲットグループのターゲット(Raisのサービス)のポート**を指定してみてください。

ネットワークインターフェイスのどれを選んだら良いか分からん！？という方は、VPC→ネットワークインターフェイスの一覧を見た時に、ELBやECSで使うセキュリティグループでフィルタをかけてあげるとそれっぽいのが出てきます。

分析結果の画像掲載は割愛しますが、割と分かりやすくどこで落ちているのか分かります。
そこの設定を再度見直してみて下さい。
また、上述した、RDSに繋がらない！等のトラブルにも使えたりします。

### 原因究明2.3 ターゲットグループのポートの確認

**ターゲットグループのポートと、ヘルスチェックのポートが一致しているか**を確認してみてください。ターゲットグループはHTTPの80なのに、ヘルスはHTTPSになっていると、エラーになります。

![Screenshot from 2022-04-07 17-37-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/59761953-1dcb-c631-6f8c-1cc8b0e4429f.png)



## 原因究明3 Rails側、コンテナ側の設定を見直す

CloudWatchのRailsのログにアクセスの形跡が無く、ネットワークも問題ない場合、Railsの設定をもう一度見直してみましょう

### 原因究明3.1　サービスのポートは本当にあっている？

`config/puma.rb`の`port`の設定が3000ではなくて3001にしていましたとかはありませんか？

- `config/puma.rb`の`port`の設定
- タスク定義のポートマッピングのポート
- ECS側のセキュリティグループで明けたポート

が正しく一致しているかを確認してください。


### 原因究明3.2 `config/environments/[環境名].rb`の`force_ssl`が`true`になっている

ネットワーク設定も問題ない、ポートも一致している、リスナーポートもHTTPの80番、ヘルスチェックも80番で通信しているはず...なのにログが一切出ない！そんな時はforce_ssl設定を疑ってみましょう。この場合も、CloudWatchのログに一切通信が出ません。設定をfalseにしたり、httpsでのヘルスチェック通信等を試してみて下さい。また、以下の記事などを参考に、上手く回避してもらっても良いかもしれません。

https://qiita.com/Shuhei_Nakada/items/a7f2fd64f0af9663ed29



## 原因究明　その他

その他、こんな所で躓いた！などあれば、コメントで教えていただけると助かります！