AWS:ChatGPT Proと進めたEC2からECS on Fargateへの移行(2026年9月・第1回)

長年運用してきたWeb環境を、Amazon EC2からAmazon ECS on Fargateへ移行しました。2026年9月、ChatGPT Proと相談しながら進めた構成の見直しと、移行時に確認した内容を3回に分けてまとめます。第1回は、移行の背景とWeb・定期処理の分離についてです。(2026/09/27作成)
サーバーラックとクラウドをつなぐネットワークのイメージ bsdrouin / Pixabay

AWS CLI参考コードについて:以下は記事の確認内容を再現するための汎用例で、当時の実行ログそのものではありません。AWS CLI v2とBashを想定しています。<…>は自分の環境の値へ置き換え、認証済みのプロファイルと対象APIを利用できる権限を用意してください。同じ記事のコードは、先頭の変数設定を行った同じシェルで実行する想定です。内部のサービス名・ID・認証情報は掲載していません。

参考コード:実行環境の指定

export AWS_PROFILE='<AWS_PROFILE>'
export AWS_DEFAULT_REGION='<AWS_REGION>'
export AWS_PAGER=''
CLUSTER='<ECS_CLUSTER>'
SERVICE='<ECS_SERVICE>'

# 接続先アカウントとロールを確認する
aws sts get-caller-identity

0.これまでの環境と今回の目的

このブログでは、Linuxの環境構築や監視設定を、実際に行った手順とともに記録してきました。2018年にはEC2とAurora MySQLの環境にZabbixを導入する手順、2019年にはUbuntuへのDocker導入を掲載しています。今回の作業は、その後も続けてきたWeb運用を見直すものです。

出発点は、既存EC2の更新でした。Amazon Linux 2からAmazon Linux 2023へ、CPUアーキテクチャもARM系へ移すところから始めています。しかし、複数のサイトを動かす中でCPU使用率が急に上がる場面があり、単体EC2のサイズを増やす方法だけでは、負荷への対応と費用の両立が難しいと判断しました。

そこで、Webをコンテナ化し、必要に応じて実行タスクを増減できるECS on Fargateへ移行しました。メールもWebと役割を分離し、既存のデータベースやキャッシュは引き続き利用する方針です。

1.移行後の構成

  • 入口:CloudflareとApplication Load Balancer(ALB)
  • Web実行環境:ECS on Fargate、ARM64/Linux
  • サイトファイル:Amazon EFS
  • データベース:既存のAmazon Aurora MySQL
  • 定期処理:EventBridge Schedulerから専用Fargateタスクを起動
  • 設定の秘密情報:AWS Secrets Manager

対象は8サイトです。サイトごとの性格や負荷を考え、一部のWordPressは同じタスクにまとめ、独立させたいサイトは分けました。すべてを一つにまとめれば管理対象は減りますが、更新や障害の影響も共有します。この分け方は、費用と運用の両方から考えました。

コンテナを置き換えても必要なファイルが残るよう、永続化するデータと実行環境も区別しています。Fargateへ移った後も、アプリケーション、データ、権限、バックアップの管理は必要です。

参考コード:サービスと稼働中のタスク定義を確認する

サービスが参照するリビジョンを取得し、CPU・メモリ・ARM64設定を確認します。ファミリー名だけで最新定義を取得すると、実際の稼働定義とずれる場合があります。

aws ecs describe-services \
  --cluster "$CLUSTER" --services "$SERVICE" \
  --query '{services:services[].{desired:desiredCount,running:runningCount,pending:pendingCount,taskDefinition:taskDefinition},failures:failures}'

TASK_DEF=$(aws ecs describe-services \
  --cluster "$CLUSTER" --services "$SERVICE" \
  --query 'services[0].taskDefinition' --output text)

aws ecs describe-task-definition --task-definition "$TASK_DEF" \
  --query 'taskDefinition.{cpu:cpu,memory:memory,networkMode:networkMode,runtimePlatform:runtimePlatform}'

公式リファレンス:aws ecs describe-task-definition

2.Webとcronを分ける

WordPressの定期処理をWeb側のアクセスや稼働台数に依存させないよう、Schedulerから専用タスクを起動する構成にしました。今回整備したWordPressの定期処理は、5分間隔で実行しています。

設定画面が「有効」になっているだけでは、処理の成功までは分かりません。次の点を確認しました。

  1. 予定した時刻にSchedulerからタスクが起動していること。
  2. タスクの終了コードが正常であること。
  3. アプリケーションの完了ログが残っていること。
  4. 失敗を受け取るキューにメッセージが滞留していないこと。

初回には、ログを書き込む権限の不足でタスクが起動できない問題もありました。必要なロググループに権限を限定して追加し、処理とログの両方を確認しています。移行元のcronも整理し、二重実行を避けました。

参考コード:定期処理の設定と終了結果を確認する

Schedulerの設定と、実際に起動したタスクの結果は別々に確認します。TASK_ARNには対象回のタスクARNを指定してください。Schedulerが起動に成功しても、コンテナ内の処理失敗がDLQへ送られるとは限りません。

SCHEDULE='<SCHEDULE_NAME>'
SCHEDULE_GROUP='<SCHEDULE_GROUP>'
TASK_ARN='<SCHEDULED_TASK_ARN>'

aws scheduler get-schedule \
  --name "$SCHEDULE" --group-name "$SCHEDULE_GROUP" \
  --query '{state:State,expression:ScheduleExpression,timezone:ScheduleExpressionTimezone,target:Target.Arn,deadLetterQueue:Target.DeadLetterConfig.Arn}'

aws ecs describe-tasks --cluster "$CLUSTER" --tasks "$TASK_ARN" \
  --query '{tasks:tasks[].{status:lastStatus,reason:stoppedReason,containers:containers[].{name:name,exitCode:exitCode,reason:reason}},failures:failures}'

公式リファレンス:aws scheduler get-schedule

3.切替後は、サイトの使い方に沿って確認する

デプロイ完了の表示に加え、タスク数、ALBのターゲットの正常性、公開URLの応答を確認しました。WordPressではトップページだけでなく、ログイン画面と管理画面への転送も確認対象にしています。

切替時には、Cloudflareとオリジン間のTLS設定が原因でログイン時のリダイレクトループが発生しました。移行対象のホストに限定してStrictの設定を適用し、解消しています。同じドメイン配下でも別の配信元を使う場合があるため、ゾーン全体を一律に変更しないことがポイントでした。

参考コード:ALBのターゲットヘルスを確認する

移行先に対応するターゲットグループを指定します。healthyの確認に加えて、通常URLの表示・ログイン・管理画面の動作を別途確認します。

TARGET_GROUP_ARN='<TARGET_GROUP_ARN>'
aws elbv2 describe-target-health \
  --target-group-arn "$TARGET_GROUP_ARN" \
  --query 'TargetHealthDescriptions[].{target:Target.Id,port:Target.Port,state:TargetHealth.State,reason:TargetHealth.Reason,description:TargetHealth.Description}' \
  --output table

公式リファレンス:aws elbv2 describe-target-health

4.自動スケールと移行後の費用

移行時はWebサービスを最小1・最大2タスクとし、CPU平均60%を目標に増減する設定にしました。実際に1タスクから2タスクへ増え、負荷が下がった後に1タスクへ戻る動作も確認しています。ただし、全サイトでピーク負荷を再現した試験まで完了したわけではありません。

また、Fargateへ移すと必ず安くなる、とは言えません。タスクのCPU・メモリ以外に、ALB、パブリックIPv4、共有ストレージ、定期処理、通信、監視の費用が加わります。移行直後の試算では、当初考えていた追加費用の上限に収まりませんでした。費用の見直しは、第3回で扱います。

参考コード:自動スケールの設定を読み取る

設定値の読み取り例です。目標CPU使用率とクールダウンを確認できます。実際に増減したかどうかは、タスク数の履歴やサービスイベントと合わせて判断します。

aws application-autoscaling describe-scaling-policies \
  --service-namespace ecs \
  --resource-id "service/$CLUSTER/$SERVICE" \
  --scalable-dimension ecs:service:DesiredCount \
  --query 'ScalingPolicies[].{name:PolicyName,type:PolicyType,tracking:TargetTrackingScalingPolicyConfiguration}'

公式リファレンス:aws application-autoscaling describe-scaling-policies

5.ChatGPT Proとの進め方

今回は、ChatGPT Proとの対話を通して現状を整理し、構成案を比較し、移行後の確認項目を詰めながら作業を進めました。選択肢を説明してもらうだけでなく、確認結果を次の判断に戻す形で伴走してもらっています。

一方、稼働中の環境で何を変更するか、旧ディスクを削除してよいかは、影響と復旧方法を確認して判断しました。移行後は旧EC2だけでなく、残ったEBSやIPアドレスも整理し、移行前のスナップショットは保全しています。

今回の移行で、Webの実行環境と定期処理の分離まで進みました。次回は、この環境へ継続的に変更を届けるために構築した、GitHub ActionsによるCI/CDをまとめます。

以上


よしまさのブログをもっと見る

購読すると最新の投稿がメールで送信されます。

About yoshimasa

埼玉県さいたま市在住、2男3女のパパです。Linux系の技術情報を中心にまとめています。1978年2月生まれ。