🙄

AWS ECS ローリングデプロイをブルーグリーンデプロイに切り替えるまでの道のり

に公開

AWS ECSでは標準的なデプロイ手法としてローリングデプロイを使用できますが、CodeDeployを使用したブルーグリーンデプロイを使用することもできます。

先日ローリングデプロイからブルーグリーンデプロイに切り替える作業を行いましたが、いくつか躓くことがあったのでまとめたいと思います。

まずはじめに

Terraformを使ってAWSにリソースを作成している前提です。

ECSサービスAとBが存在しており、必要であればロードバランサー(以下ALB)のリスナールールでECSサービスBへリダイレクトするようにしていました。

セキュリティグループやALB、ターゲットグループ、ECSサービス、タスク定義などの構成要素は現在稼働しているものと並行稼働することとし、ブルーグリーンデプロイ用の環境が立ち上がったら、トラフィックを切り替えるという流れで切り替える予定でした。

今回ブルーグリーンデプロイの導入対象はECSサービスAのみだったため、ECSサービスAに関する構成要素のみを新たに並行稼働させながら導入作業を進めるという想定です。

ここに躓いた

ターゲットグループは1つのALBにのみ紐付けられる

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-target-groups.html

ターゲットグループは1つのALBにのみ紐づくため、複数個のALBに紐づけようとすると、エラーになります。

ECSサービスBは既存の環境をそのまま使用する想定だったので、ECSサービスAのために立ち上げた新しいALBにECSサービスBのターゲットグループを紐づけるには現稼働中のALBからECSサービスBのターゲットグループを一度切り離す必要がありました。

切り離してしまうとダウンタイムが発生してしまうので、この場合はECSサービスBも新しい環境を立ち上げておくなどの工夫が必要でした。

ECSサービスとターゲットグループが紐づいていない

Terraformを使ってAWSのリソースを作成、更新していましたが、最終的な構成に作り上げるまで本番環境ではTerraform apply実行によるエラーが起きませんでした(ステージング環境では何度かエラーが起きていた)。

そのため、Terraformで実行した構成が反映されているだろうという認識で作業を進めた結果、デプロイを実行してもECSサービスのインスタンスがターゲットグループに紐づいていないという状況が発生しました。

結局のところ、ECSサービスを一度削除し、Terraformを再度反映して、ECSサービスを再作成したところターゲットグループの設定変更が反映されました。

ブルーグリーンデプロイ中はDBのコネクション数が増加

ブルーグリーンデプロイの実行中は旧タスクと新タスクが混在します。そのタスクにAPIサーバーなどのDBとのコネクションを作成するものがあれば注意が必要です。

旧タスクと新タスク両方のコネクションが作成されるため、通常稼働で間に合っているはずのコネクション数が足りなくなる可能性があります。

https://repost.aws/ja/knowledge-center/rds-mysql-max-connections

コネクションが不足した場合はDBのインスタンスタイプを上げて、コネクション数を増やすのがベストプラクティスのようです。

コネクション数増加はブルーグリーンデプロイによる一時的なものなので、パラメータグループのmax_connectionsを増やしてもいいかもしれません...が、十分に検証する必要がありそうです。

CodeDeployとターゲットグループの整合性

CodeDeployではブルーグリーンデプロイをしたときのターゲットグループの情報を保持しているため、CodeDeployの状態と現在の状態が異なるとCodeDeployでのデプロイがエラーになることがあります。

例えば一度ブルーグリーンデプロイを行い、グリーンのターゲットグループが本番環境として使用されていたとします。

このとき、Terraform applyや何らかの検証での操作でブルーのターゲットグループになった場合(ブルーグリーンデプロイの影響による変更以外の場合)にブルーグリーンデプロイを行うとCodeDeploy上でエラーになります。

この場合はグリーンのターゲットグループに手動で戻す必要があります。

サービス検出に注意

こちらは先日書いた別記事にて
https://zenn.dev/smartcamp/articles/819dfc0c15dd52

迂闊にTerraform applyすると爆死

ブルーグリーンデプロイをするたびにALBのリスナールールに紐づくターゲットグループは切り替わります。

そのため、Terraformのステートと異なってしまうとapplyするときに差分として現れることがあります。

これを迂闊にapplyすると、ALBのリスナールールが書き変わってしまい、インスタンスが登録されていないターゲットグループが本番環境で使用され、ECSサービスにリクエストが到達しなくなるということがあるので注意が必要です。

ChatOpsは神

これは躓いたことではありませんが、ChatOpsでブルーグリーンデプロイをできるようにしておいた方が絶対にいいです。

ブルーグリーンデプロイはいくつかのステップがあるので、ECSとCodeDeployをきちんと理解していなければ、AWSコンソールからデプロイをしていくのはそれなりに難易度が高いです。
リリースのたびにAWSコンソールを開いてぽちぽちするのもしんどいと思います。

リリース頻度を高めるという意味でもChatOpsはかなり有用です。

弊社ではSlack経由でブルーグリーンデプロイを実行できるようにしていますが、Cloudflare Workers上にSlack Botを作成しています。

https://github.com/slack-edge/slack-cloudflare-workers

まとめ

ECS完全に理解したと思っていましたが、ローリングデプロイからブルーグリーンデプロイに切り替えるだけでも結構苦労してしまいました。まだまだ修行が足りません。
ECSチョットワカル...

SMARTCAMP Engineer Blog

Discussion