EC2 から ECS on Fargate に移行して、運用と障害対応が楽になった話

はじめに

こんにちは、株式会社Spacelyでバックエンドエンジニアをしているtoshichanappです。 本記事では、Rails アプリケーションを EC2 ベースの運用から ECS on Fargate へコンテナ化したことで、 運用・障害対応・デプロイ体験がどのように変わったのかを、運用者視点の体験談として紹介します。

採用している主な構成は以下です。

  • コンテナ基盤: ECS on Fargate
  • デプロイツール: ecspresso
  • IaC: Terraform

コンテナ化前の構成と課題(EC2 時代)

EC2 運用の負担

EC2 ベースの運用では、以下のような保守作業が定期的に発生していました。

いずれもアプリケーション開発とは直接関係がなく、
運用コストとして確実に時間を消費する作業でした。

スケールの難しさ

当時はオートスケーリングは導入しておらず、EC2の手動での立ち上げ、Ansibleでの構築、ALBへの接続といった手順を踏んでいました。そのため、負荷が急増した際の対応はどうしても後手に回りがちでした。


コンテナ化によってよくなったこと

ECS on Fargate への移行によって、改善を実感したポイントは大きく次の4つに分けられます。

  • 運用: インフラ保守作業から解放され、アプリケーションに集中できるようになった
  • 障害対応: 原因切り分けと調査が速くなり、属人化しにくくなった
  • デプロイ / リリース: 実行単位が明確になり、失敗しにくい構成になった
  • バッチ処理 / スケーリング: 高負荷処理やスケール対応を設計で解決できるようになった

以下、それぞれの観点ごとに詳しく紹介します。


運用

EC2 固有の運用作業から解放され、日常運用の負担が大きく減りました。

インフラ運用そのものの負担が減った

ECS on Fargateへの移行により、EC2固有の運用作業が不要になりました。 インフラ管理に費やしていた時間が減り、その他の開発や改善に集中できるようになりました。

CPU/メモリの調整が容易になり、リソース管理への意識が向上

EC2時代は、CPUやメモリの変更に心理的なハードルがありました。なぜなら、インスタンスタイプの変更、再起動に伴う影響範囲の調整、作業タイミングの調整などが必要だったからです。 一方、ECS on Fargateでは、タスク定義を変更するだけで、CPUやメモリの調整ができ、サービス単位で段階的に反映できます。 これにより、「少し増やして様子を見る」「問題があればすぐ戻す」といった試行錯誤が現実的になりました。 結果として、リソース不足を我慢する運用や、勘と経験に頼った割り当てではなく、実測に基づいて前向きにチューニングするという姿勢でリソース管理に向き合えるようになったと感じています。

障害時も「人が張り付く運用」から脱却できた

  • 自動復旧・再起動を前提とした構成
  • 一時的な障害で夜間対応が発生しにくくなった

常時監視や緊急対応を前提としない運用に近づいたと感じています。


障害対応

障害発生時の「切り分け」「調査」「振り返り」が圧倒的にやりやすくなりました。

アプリケーションサーバ / Sidekiq を分離できたことで切り分けが容易に

アプリケーションサーバとSidekiqをコンテナ単位で分離したことで、「アプリケーションサーバ起因の問題なのか」「Sidekiqサーバ起因の問題なのか」を、 コンテナ単位でリソース使用状況を把握できるようになり、下記のようなトラブルの原因がわかり解決できました。

解決できたトラブル例

no space left on device

  • Sidekiq jobで動画サムネイル生成に ImageMagick を使用
  • アプリケーションサーバ、Sidekiq両方でtmpファイルが削除されずに溜まり続けていた
  • このためにEBSをアタッチしていたが、外すことができた

Out Of Memory (OOM)

タスク定義ごとにメモリを分けて考えられるようになり、
リソース設計の見直しがしやすくなりました。

調査ログが残るようになった

EC2時代はAWS Systems Manager Session Managerを利用していましたが、「誰が」「いつ」「何をしたのか」という情報が残りませんでした。

ECS移行後はecs execを利用し、実行ログをS3に保存する設定(execute_command_configurationの有効化)を行うことで、調査内容を後から正確に振り返れるようになりました。

結果として、

  • 属人化しにくい
  • 「なぜ直ったのか分からない」を減らせた

という点でも運用が安定しました。


デプロイ / リリース

リリース作業が「失敗しにくい構造」になり、精神的な負担が減りました。

マイグレーション事故が減った

EC2 / CodePipeline 時代は、CodePipeline の timeout によりrailsのmigration処理は中断されるため DDL は実行されたがschema_migrationsが更新されないといった 中途半端な状態が発生することがありました。

コンテナ化後は、

  • migration を ワンショット ECS タスクとして実行
  • 実行単位が明確になり、途中失敗が起きにくくなった

これにより、マイグレーションに対する不安要素が1つ減りました。

CodePipeline をやめられた

CodePipelineからGitHub Actions + ecspresso構成に変更したことで、以下のメリットがありました。

  • シンプルなデプロイ: ecspressoがTerraformのtfstateを参照する機能により、ARNのハードコーディングや環境別の分岐処理を排除。独自のデプロイシェルスクリプトの管理が不要に。
  • コスト削減: assetsなどのアーティファクトをS3に溜めなくなり、S3コスト削減にもつながりました。

バッチ処理 / スケーリング

スケールや高負荷処理を、人手ではなく「設計」で扱えるようになりました。

スケールが「設計で解決できる」ようになった

ECS on Fargate 移行後は、

  • CloudWatch Alarm
  • 時間指定スケール

を組み合わせた オートスケールを導入しました。

Sidekiq のキューが一時的に大量に溜まるケースでも、

  • 待ち時間が大幅に短縮
  • 人が張り付いて対応する必要がなくなった

という効果を実感しています。

オートスケールに関してはこちらの記事もご覧ください。

ECS でオートスケーリングを設定しました! - Spacely Tech Blog

重たいバッチを安全に並列実行できるようになった

1回きり・高負荷なバッチ処理をECS Run Taskで並列実行できるようになりました。これにより、アプリケーションサーバや常駐プロセスへの影響を最小限に抑えながら、安全に処理を進められるようになりました。

また、Task Definition/Service Definitionを見るだけで、「どの処理が」「どの用途で」「どのリソース量で」動いているかが設定として可視化されたことも大きな利点です。

コンテナ化後にハマったポイント

特定 user 前提の処理

EC2 では暗黙的に存在していた user に許可していた実装があったためDockerfile 内で user を明示的に作成する必要がありました。

スケールイン時のジョブ中断

こちらは下記記事をご覧ください。

ECSオートスケール × Sidekiqで発見した“スケールインの落とし穴” - Spacely Tech Blog


まとめ

ECS on Fargate へのコンテナ化によって、

  • インフラ運用の負担が減った
  • 障害時の原因特定が速くなった
  • スケールやバッチ実行を「設計」で解決できるようになった

特に、

  • task / service definition による可視化
  • ecspresso + Terraform によるシンプルなデプロイ
  • ecs exec による調査ログの蓄積

は、「コンテナ化=インフラが楽になる」という利点以上に、チーム全体の開発体験を改善する要素だったと感じています。 EC2運用やスケール・バッチ対応に課題を感じている方の参考になれば幸いです。


🚀 エンジニア募集中

Spacely では、

  • ECS on Fargate を使ったコンテナ運用改善
  • Rails / Sidekiq を中心とした非同期処理基盤改善
  • インフラ・運用・障害対応まで含めた設計改善

に取り組んでいます。 今回の記事のような改善や設計に興味がある方と、 一緒により良いシステムを作っていけたら嬉しいです。

少しでもご興味がある方は下記よりご連絡ください!

採用ページ