背景
CDK + ASG(EC2 Auto Scaling Group)で構築していた Spring Boot アプリの CI/CD 構成を、ECS Fargate + Docker に置き換えました。
インフラは CDK Pipelines、アプリのビルド・デプロイは GitHub Actions(OIDC 認証)に分離する構成です。
【インフラ担当】CDK Pipelines
GitHub push → CodePipeline → cdk synth → CloudFormation (VPC/ECR/ECS/RDS/ALB)
【アプリ担当】GitHub Actions(app/ or Dockerfile 変更時のみ)
Docker build → ECR push → ECS タスク定義更新 → ローリングデプロイ
移行してみて、EC2構成との違いが大きかった点を5つにまとめます。
1. UserData / appspec.yml が Dockerfile 1枚に集約される
EC2 + CodeDeploy 構成では、以下が全部必要でした。
- Launch Template の UserData(Java・Tomcat・CodeDeployエージェントのインストールスクリプト)
-
appspec.yml+scripts/*.sh(デプロイフック)
ECS Fargate ではこれが Dockerfile 1つに集約されます。マルチステージビルドで Maven → WAR → Tomcat コンテナを作る形です。
# ビルドステージ
FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /app
COPY . .
RUN mvn clean package -DskipTests
# 実行ステージ
FROM tomcat:10.1-jdk17
COPY --from=build /app/target/*.war /usr/local/tomcat/webapps/ROOT.war
2. スケーリングが「コマンド一発」になる
ASG は CPU 閾値・CloudWatch アラーム・スケーリングポリシーの設定が必要でしたが、ECS は desired_count を変更するだけです。
aws ecs update-service \
--cluster my-cluster \
--service my-service \
--desired-count 2 \
--region ap-northeast-1
コンテナ単位の起動なので30秒程度で反映され、EC2起動を待つASGより速いです。
3. デバッグ接続が SSM Session Manager → ECS Exec に変わる
EC2 では SSM Session Manager でインスタンスに接続していましたが、ECS Fargate では ECS Exec でコンテナ内シェルに直接入れます。
aws ecs execute-command \
--cluster my-cluster \
--task <task-arn> \
--container my-app \
--interactive \
--command "/bin/sh" \
--region ap-northeast-1
ログの扱いも変わります。コンテナのTomcatは catalina.out のようなログファイルを持たず、標準出力に直接書き出してCloudWatch Logsに転送される構成にしています。
4. インフラとアプリのデプロイ経路を分離した理由
CDK Pipelines(インフラ)と GitHub Actions(アプリ)を分けているのは、デプロイ頻度が違うためです。
| 変更頻度 | デプロイ手段 | |
|---|---|---|
| インフラ(VPC/ECR/ECS定義/RDS/ALB) | 低 | CDK Pipelines(push契機) |
| アプリ(Spring Bootコード) | 高 | GitHub Actions(app/変更時のみ起動) |
GitHub Actions 側は OIDC 認証でIAMロールをAssumeするため、リポジトリにAWSアクセスキーを置く必要がありません。
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<account>:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:<owner>/<repo>:ref:refs/heads/main"
}
}
}
5. ハマったポイント:ECSタスクがSTOPPEDを繰り返す
初回デプロイ時、プレースホルダーイメージ(公式Tomcat)のpullに失敗してタスクが起動→停止を繰り返すことがありました。ECSコンソールの「停止タスク」→「停止理由」に具体的な原因が出るので、まずそこを確認するのが早いです。
他にも詰まりやすいポイントの一覧です。
| 症状 | 原因 | 対処 |
|---|---|---|
| GitHub Actionsが失敗(OIDCエラー) | IAMロールの信頼ポリシー不正 |
AWS_ROLE_ARN と信頼ポリシーの sub を確認 |
| GitHub Actionsが失敗(ECR push) |
ecr:GetAuthorizationToken 権限不足 |
IAMロールのポリシーを確認 |
| ECS Execが接続できない |
enable_execute_command 未設定 |
ECSサービス設定で有効化 |
まとめ
EC2 + CodeDeploy から ECS Fargate + GitHub Actions への移行で、OS管理・エージェント管理から解放され、デプロイ設定が Dockerfile 1ファイルに集約されました。CDKのコード全文や、GitHub連携の初期セットアップから含めた手順を追いたい場合はこちらにまとめています。