【AWS】Codedeployのタイムアウトエラーにより「置き換えタスクセットのデプロイ」が一向に終わらない件の対応方法

# エラー内容
* AWS Codedeployを実施したところ、以下のエラーが表示されてしまった。
    * 以下は1時間待った場合。「ステップ1. 置き換えタスクセットのデプロイ」が33%のところで止まってしまい一向に進まなくなる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/f3ae5911-1bac-6ce4-f301-0b59e4397404.png)

```
The deployment timed out while waiting for the replacement task set to become healthy. This time out period is 60 minutes.
```

## 前提
* AWS Codebuildの実施（Image作成）は成功している
* デプロイ方法は、ブルーグリーンデプロイメントの手法をとっており、以前はこのやり方でデプロイが成功していたが、最近実施したらできなくなっていた

## 結論
* Dockerfileでnginxのシェルスクリプトを編集したことが問題でした。
* Buildでイメージ作成は成功していたので、この辺はスルーしていたのですが、Deployが成功していた日付に近いコミット履歴まで戻してみようとコミットをRevertしてみることに。すると、とあるコミットの取り消しによりDeployが正常に進むことが判明。そのコミットでは、Dockerfileに記述のあるnginxのシェルスクリプトが編集されていたので、その変更が悪さをしていたことがわかりました。
    * ここの詳細はもう少し調べてから別途更新しようと思います
* ビルドが成功しているからといってCodeDeployやELB周りばかりに目を向けて問題を探していると時間を食ってしまうので、そこだけ強く申し上げたいと思います...。
* 以下、他に確認した事項について備忘録として残しておきます。

# やってみたこと（確認したこと）
* プレースホルダ側の設定確認
* ELBのルール(リスナー)設定確認
* ELBのヘルスチェック設定の確認
* アプリ側（djangoの`ALLOWED_HOSTS`）の設定確認
* デプロイグループの再ルーティング設定確認
* デプロイグループのロール設定確認
* Githubのコミット履歴日付から確認

## プレースホルダ側の設定確認
* 参考記事：[CodeDeployのInstallイベントが一向に終わらないので原因切り分けと設定を見直した箇所](https://dev.classmethod.jp/articles/install-event-of-codedeploy-does-not-complete/)
* プレースホルダ（`taskdef.json`/`appspec.yml`を用意する方）を利用した設定だったので、両方確認。
    * `taskdef.json`の内容に誤りがないか確認したが、問題なかった。
* ちなみに、もし問題がある場合は、失敗したデプロイのリビジョンの`appspec.yml`と、該当の`taskdef.json`のfamily名やAWSアカウント名が一致しているか確認すると良いとのこと。

## ELBのルール(リスナー)設定確認
* 本稼働ポート・テストポートどちらもターゲットグループ・グリーンに向いており問題ない。（今回はグリーンからブルーに切り替えるデプロイ）

## ELBのヘルスチェック設定の確認
* エラーログの内容に"healthy"とあるので、ヘルスチェック設定を確認。
    * 参考：[AWS Blue/Green CodeDeploy to ECS install lifecycle event timesout](https://stackoverflow.com/questions/57857709/aws-blue-green-codedeploy-to-ecs-install-lifecycle-event-timesout)
    * 参考：[CodeDeploy(Blue/Green)でinstallが50%から終わらない](https://qiita.com/Sicut_study/items/0ccbb889094c6f6e3876)
* ただし、ターゲットグループを確認しても、現状healthyの状態なので問題なさそう。ちなみに、以下curlコマンドで詳細に確認できる。HTTPステータスコードで200、301、302、403、502などが返ってくるので、これによって原因が特定できる場合もある。

```
$ curl -v http://public-xxxxxxxx.ap-northeast-1.elb.amazonaws.com:[ポート番号]
```

* 何が原因かわからなかったので、試しにヘルスチェックを別のパスにして再度CodeDeploy実施してみたが、結果は変わらず。

### アプリ側（djangoの`ALLOWED_HOSTS`）の設定確認
* 今回はPythonのアプリケーションフレームワークであるdjangoを利用しています
* `ALLOWED_HOSTS`に追加していないとヘルスチェックに失敗する？とのこと。エラーログに"healthy"とあるので一応確認。
    * 参考：[AWS ALB のヘルスチェックと Django の ALLOWED_HOSTS](https://www.utakata.work/entry/2021/03/24/114349)
* `settings.py`を確認したが、ワイルドカードを使ってすべてのホストを許可しているので関係ない。

```
ALLOWED_HOSTS = ['*']
```

* というか、ヘルスチェックは既に成功しているし、「`ALLOWED_HOSTS`に追加されていないホスト名でアクセスすると、ステータスコード 403 のエラーになる」はずなので403が出ていない時点でここの設定は関係ないと思われる。

### デプロイグループの再ルーティング設定確認
* CodeDeployでの再ルーティングの指定時間に問題がある可能性も考えたが、「すぐにトラフィックを再ルーティング」の設定になっていたので問題ない。
    * 参考：[CodeDeployでトラフィックの再ルーティングを指定時間までに実行しないとタイムアウトする](https://dev.classmethod.jp/articles/codedeploy-traffic-rerouting-timeout/)
* ECS側Service側のLogを見たがそれらしい記述はない（ELB-HealthCheckerが動いているだけだった）
    * 参考： [【トラブルシューティング】 CodeDeploy detected that the replacement task set is unhealthy.](https://qiita.com/momotaro98/items/d63f6836482a0d60ea96) 

### デプロイグループのロール設定確認
* 該当デプロイグループのロールを確認したが、権限不足という可能性はなかったので問題ない。

### Githubのコミット履歴日付から確認
* 参考: [CodeDeploy によるECS でのBlue/Greenデプロイの話](https://tech.isid.co.jp/entry/2022/01/11/CodeDeploy_%E3%81%AB%E3%82%88%E3%82%8BECS_%E3%81%A7%E3%81%AEBlue/Green%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%81%AE%E8%A9%B1)
* 上記記事に、以下のように記載がある...が、  Buildは成功しており`taskdef.json`も問題なかった。ソースコードの問題ではないだろう...（と思っていた）

> Dockerfileに不備があり、起動できない状態のコンテナーをデプロイしようとしているのが原因

* Deployが失敗した日付あたりのGithubのコミット履歴を見返すと、Dockerfileをいじっていたので、念の為そこのコミットをREVERTしてみたら、解決しました（=冒頭の件）。
* 色々試行錯誤したエラー対応でした（疲れた...）。