トラッカーズマネージャーをEC2からECS on Fargateに移行した話

FINAL FANTASY XIV 暁月のフィナーレをアーリーアクセスから駆け抜け、万魔殿パンデモニウム辺獄編零式を踏破して装備集めをしつつAzoopでソフトウェアエンジニアとして働いている武田です。メインクエストのストーリー、とてもよかったですね。ララフェルパンチ!
このまま暁月のフィナーレの感想を書き続けたいのですがやっぱり会社のnoteですのでAWS EC2上で動いていた運送会社の業務支援SaaSのトラッカーズマネージャー(以下『トラマネ』)をECS on Fargateに移行した話を書きます。

EC2時代の構成と問題

トラマネのステージングと本番環境は2019年のβ版リリース以来AWS EC2上で動作していました。GitHub上にあるリポジトリのリリース用ブランチにマージされるとCircleCIのジョブがキックされ自動的にデプロイされるフローが整備されていました。

EC2時代の構成図

 しかしお客様の利用が増え、機能が拡充されていく中で以下のような問題が出るようになりました。

  1. アセットのビルドに時間がかかり時々リソース不足で失敗する
    デプロイにテストを含めて1時間以上掛かる状態になっていました。またAsset Pipeline、特にWebpackの実行時にメモリ不足になり異常終了しデプロイに失敗することが起きるようになったためマシンスペックをそれに合わせて引き上げるといった金銭コストの増加につながっていました。

  2. ミドルウェアのアップデート対応などインフラの運用業務の人的コストが大きい
    インフラ専門のチームがまだなく、エンジニアは機能開発をメインに担っており片手間で運用業務にあたっている状態になってしまっておりミドルウェアのアップデート対応は検証や実作業に大きく時間を取られる作業のためとても大きな負担になっていました。

また、トラマネの開発を行う開発者が普段使っている開発環境はDockerコンテナで動いておりステージングや本番環境と開発環境のインストールされているライブラリ類やパッケージのバージョンといった動作環境の差異による不具合が時々起きていました。これらの問題を解決するためステージングと本番環境をEC2からECSに移行することになりました。

Fargateを採用した理由

ECSの起動タイプにはコンテナを動かすインスタンスを自分たちで用意し運用する「EC2タイプ」とAWSがインスタンスを用意してくれるサーバーレスな「Fargateタイプ」の2つのタイプがあります。
EC2タイプは自分たちでインスタンスを用意しミドルウェアのセットアップやスケーリングを考えなければならない分、リソースの細かい調整ができインスタンスにSSH接続し調査や作業が可能です。そのため従来の構成とほぼ変わらない運用が可能です。
一方Fargateはインスタンスの運用はすべてAWSが行っています。コンテナを動かすインスタンス部分は考える必要がない分、リソースはタスクに割り当てるvCPUとメモリ数を用意された選択肢から選択するのみで細かく調整ができません。またAWSが管理しているためインスタンスにSSHして調査や作業ができず料金も少し割高です。
これらを比較検討した結果、「インフラ運用の専門チームがなく片手間状態になってしまっている我々にとっては多少割高でも運用に係る人的コストを考えるとFargateのほうがよい」ということになりました。

移行後

以下はFargateに移行した後の簡単な構成図になります。(ステージングもほぼ同じ構成です)
アプリケーションサーバとSidekiqサーバがEC2からECS on Fargateに移行しデプロイがCircleCI + CapistranoからCodePipelineを使ったBlue/Greenデプロイに変わりました。

ECS on Fargateを用いた構成図

また、Cronによってスケジュール実行していたバッチ処理は複雑なスケジュール組みや依存がなかったためEventBridgeを用いてタスクを実行するようにしました。
また従来サーバにSSHして実行していた調査や作業は簡単なものであればECS Execで実行中のアプリケーションコンテナに接続して行うようにしました。(ファイルのやり取りは専用のS3バケットを経由)
これによってECS Execを実行するためのロールを割り当てている踏み台以外のEC2ホストが不要になりました。

移行によりCodeBuildを使いアセットを含んだイメージをビルドしECRにプッシュ、ECSに展開するようになったためアセットビルドに備えた高スペックなEC2を常に用意する必要がなくなりFargateを採用したことでコンテナをホストするサーバを管理する手間から解放されました。
CodePipeline(CodeBuild)をフル活用しているため多くなった時間課金やFargateがEC2タイプに比べて少し割高なこと、VPCエンドポイントの利用などで金銭的なコストは上がりました。しかし管理やデプロイに失敗したときのリカバリといった作業にあたる人的コストを考えると全体的なコスト感は下げることができたと思います。(タスクに割り当てるリソースの最適化やステージングが24時間起動している状態なのでそのあたりをちゃんとやれれば金銭的なコストも下がると見ています)

移行中の壁と工夫

terraformの導入

サービス開始時は心込めて(?)手動で構成されていたインフラですが、「なぜこのリソースが作られたのかわからない」「謎のセキュリティグループがある」といった経緯不明なリソースが作られていたり重要な変更が口頭共有のみで誰のレビューを通ることなく実行されているようなカオスな世界になってしまっていました。
それらのカオスな状態を整理・解消するためterraformの導入に踏み切りました。(CDKなど選択肢はありましたが私が慣れているのがterraformだったので雑に導入しました)
導入にあたっては100%管理下に置くと時間が掛かりすぎるという判断からセキュリティグループやVPCといった勝手に変更されるとまずそうなところをまずはterraform管理下に置くようにしています。
専用のリポジトリにPRを作成するとGithub Actionsによりterraform planが実行され、mainブランチにマージされると同様にterraform applyが実行されるようにしています。変更はvalidateとplanの実行成功と1人以上のレビューを通すことを必須にしておりこれにより経緯不明で重要な変更がされることを防いでいます。

SidekiqコンテナのBlue/Greenデプロイの実現

トラマネの非同期処理はSidekiqを利用しています
Sidekiqに限らずELBに紐付かないECSタスクはCodeDeployによるBlue/Greenデプロイができないという制約があります。
Sidekiqだけローリングアップデートにしたり独自でデプロイフローを作ることを含めて検討しましたが最終的にはサイドカーでNginxを起動し無理やりELB配下に置くことでデプロイ方法を統一することにしました。
一方でBlue/Greenデプロイのためだけにしか使わないELBが必要になるため、今後のアップデートでELBがなくてもBlue/Greenデプロイができるようにならないか期待したいと思います。

デプロイに掛かる時間をなるべく短くするための工夫

トラマネは開発中やリリース用ブランチにマージしたときの他にデプロイ時にもテスト(RSpec)を実行するようにしています。
移行を始めた当初はテストの実行が成功したときにイメージのビルド、ECRへプッシュをするようにしていました。
そのため初期型のデプロイフローが完成した時点ではデプロイ時間は45分程度と確かに(EC2時代に比べたら)短くなったけどまだまだ時間がかかる様子でした。
そこでデプロイ時間のさらなる短縮のため「テストの実行とイメージのビルドを並列で行う」ようにしました。テストが失敗すればパイプラインはそこでストップするのでECRへのプッシュは行われますがデプロイはされないようになっています。(ECRへ使われないイメージがプッシュされることによるコストはかかりますが無視できる範囲なのでそっとしています)
さらにテストもControllerのテストは実行時にrender_viewしているspecが含まれるためAsset Pipelineが実行され時間がかかるため分割しControllerのテストとそれ以外のテストが並列で実行されるようになっています。Controller以外のテストはparallel_testsを使ってさらに高速化を図っています。

これらの工夫とCodeBuildのキャッシュの活用により現在は概ね30分未満でデプロイされるようになっています。

まとめ

今回はトラマネのインフラをEC2からECS on Fargateへ移行した話を書きました。
インフラは機能開発や不具合修正と比べればプロダクトへ直接的な成長につながることが見えにくいため放置されがちです。ですがインフラに問題があると進化についていけなくなったりセキュリティ問題等の原因になりプロダクトをぶち壊すリスクを抱え込む結果になります。
トラマネはFargateを採用したことで人手が少ない中でも運用を回すことができるようになりプロダクトの開発にある程度集中できる環境を整える最初の一歩を踏み出すことができました。
まだまだ改善できる・しなければならない点は多くあるので引き続き整備に取り組んでいきます!


この記事が気に入ったらサポートをしてみませんか?