Claude Code × Spec Kit で App Runner から Amazon ECS Express Mode の移行検証を実践

記事タイトルとURLをコピーする

こんにちは、近藤(りょう)です!

2026年3月31日、App Runner の新規顧客向け提供を2026年4月30日で停止するというアナウンスがありました。

AWS サービスの提供状況に関する最新情報 - AWS

移行先として新機能である Amazon ECS Express Mode が推奨されていることから App Runner から ECS Express Mode への移行検証を実施しています。

App Runner 通知画面

せっかくなので Claude Code と Spec Kit を使い開発以外の「インフラストラクチャーにおける仕様駆動開発(Spec-driven Development)」を生成AIを用いて実現できるかの検証をして見ました。

要件定義から実装・検証までを対話的に進める「AI駆動型インフラ開発」の実践例ご紹介します。

App Runner とは?

App Runner は、コンテナやソースコードから簡単にWebアプリを公開できるマネージドサービスです。

Docker イメージを指定するだけでデプロイできたり、ロードバランサーやスケーリングも自動で面倒を見てくれるので「とりあえず動かしたい」という用途ではかなり便利なサービスです。

docs.aws.amazon.com

Amazon ECS Express Mode とは?

Amazon ECS Express Mode は ECS(Fargate)をベースにロードバランサーやオートスケーリング、ネットワーク設定などをまとめて自動構成してくれる仕組みです。

シンプルな API / コマンドで、可用性の高いコンテナアプリケーションをそのまま起動できるようになっており、ECS を直接触るときに必要になる周辺リソースの設定をある程度省略できます。

実行基盤は Fargate なのでタスク実行に応じた従量課金になりますが、ALB などの周辺リソースは常時起動となるため、コストは継続的に発生します。

aws.amazon.com

今回の Claude Code と Spec Kit の利用方法

今回の検証は、Claude Code と Spec Kit を組み合わせて進めています。

Claude Code を起動し、Spec Kit を実行して要件を定義、その後、仕様・計画・タスクを生成した上で実装および実行までを行う構成としています。事前に詳細な設計を固めるのではなく、実行しながら要件を補完・修正していく進め方としています。

実行環境は以下の通りです。

  • VS Code + Claude(Enterprise)
  • VS Code に Spec Kit をインストール

以下、初回のプロンプトです。

SpecKitを起動させて仕様駆動開発をしたいので手伝ってください。
SpecKitの利用方法はこれを確認してください。
https://github.com/github/spec-kit
なお、specify CLIはすでにインストール済みです。

(例)初回のプロンプトイメージ

Spec Kit を使った仕様駆動開発の進め方を教えてくれます。 ここから、仕様を決めて実装まで進めていきます。

(例)初回のプロンプト応答

App Runner から ECS Express Mode への移行検証の概要

AWS のドキュメントをベースに移行検証を行います。

docs.aws.amazon.com

移行検証の構成

App Runner から ECS Express Mode へ段階的にトラフィックを切り替える構成としています。 実際の移行では、データベース接続や環境変数などの設定も含めて考慮する必要があるため、これらを利用するような前提で移行検証を行っています。

移行検証の構成

本検証は以下の前提で実施しています。

  • VPC / パブリックサブネット(2つ以上)/ Internet Gateway が作成済みであること
  • Route 53 にホストゾーンが作成済みであること
  • AWS Certificate Manager(ACM)に証明書(ワイルドカード含む)が発行済みであること
  • 上記以外の設定は行っていないこと(セキュリティグループや IAM ロールも未設定の状態)

Claude Code × Spec Kit の流れ

Spec Kit の初期化(specify init)

初回のプロンプト後、Claude Code 上で Spec Kit を初期化し、ワークフローを開始します。

Claude:

まず specify init でプロジェクトを初期化する必要があります。

何を作るプロジェクトですか? プロジェクトの概要を教えてください。名前と大まかな目的がわかれば、specify init
を実行してワークフローを開始できます。
(ディレクトリ名が apprunner-ikou-v2 なので AWS App Runner 関連のプロジェクトでしょうか?)

私:

App Runnerが利用できなくなるようです。
ドキュメントでは、Amazon ECS Express Modeへの移行の案内があったため、移行した時の動作を確認したいです。
以下、ドキュメントです。
https://docs.aws.amazon.com/ja_jp/apprunner/latest/dg/apprunner-availability-change.html

Claude:

● Fetch(https://docs.aws.amazon.com/ja_jp/apprunner/latest/dg/apprunner-availability-change.html)
  ⎿  Received 42.4KB (200 OK)

● ドキュメントを確認しました。App Runnerのサービス終了(2026年4月30日〜)に伴い、ECS Express Modeへの移行検証をするプロジェクトですね。

  Spec Kitでプロジェクトを初期化します。
● Bash(specify init . --here --integration claude --force 2>&1)

~省略~

● 初期化成功しました。では早速ワークフローを開始しましょう。

  まず ステップ1: プロジェクト原則の確立 から始めます。

初期化完了後、Spec Kit のワークフローが開始されます。以降は対話形式で要件を Claude と整理しながら仕様を決めていきます。

Spec Kit のワークフロー

  • /speckit.constitution(constitution.md を生成)
    • ルール:プロジェクトの原則・制約を定義
  • /speckit.specify(spec.md を生成)
    • 要件:ユーザーストーリーと受け入れ条件を定義
  • /speckit.plan:(plan.md を生成)
    • 設計:技術方針・構成・依存関係を整理
  • /speckit.tasks:(tasks.md を生成)
    • タスク:タスク一覧を生成
  • /speckit.implement:tasks.md をもとに実装・実行
    • 実装:実行コマンドではなく、実行 → エラー解析 → 修正 → 再実行、というサイクルを Claude Code が自動で回します。

生成されたドキュメント

ファイル 内容
.specify/memory/constitution.md ルール:原則(移行安全性・検証駆動・IaC など)を定義
specs/001-.../spec.md 要件:ユーザーストーリーと受け入れ条件
specs/001-.../plan.md 設計:技術スタック・依存関係・構成
specs/001-.../tasks.md タスク:タスク一覧(優先度・依存関係・並列可否)
specs/001-.../quickstart.md 実装:実行手順・トラブルシュート

要件の伝え方

speckit.specify 実行時は、箇条書きベースで要件を伝えています。今回は、初回でドキュメントをインプットしていたため、ルール や 要件はある程度自動で解釈・生成されていました。

Claude:

~省略~

  ✅ /speckit.specify — 仕様書の作成

  specs/001-apprunner-to-ecs-express-migration/spec.md に3つのユーザーストーリーを定義しました:
  - P1: ECS Express Mode でアプリが正常動作すること
  - P2: Route 53 加重ルーティングで段階的トラフィック切り替えができること
  - P3: カスタムドメイン・HTTPS が引き継がれること(オプション)

  ---
  次のステップ 

  ┌──────────────────┬────────────────────────────────────────────────────────┐
  │     コマンド     │                          内容                          │
  ├──────────────────┼────────────────────────────────────────────────────────┤
  │ /speckit.clarify │ Edge Cases(Secrets Manager 対応など)を深掘りする場合 │
  ├──────────────────┼────────────────────────────────────────────────────────┤
  │ /speckit.plan    │ 技術スタックと実装計画を作成する                       │
  └──────────────────┴────────────────────────────────────────────────────────┘

  /speckit.plan に進みますか? その前に、現在の App Runner
  サービスの設定(コンテナイメージ、ポート番号、環境変数、カスタムドメインの有無)について教えていただけると、より具体的な計画が立てられます。

■ 1回目

私:

コンテナイメージ: サンプルコンテナアプリを新規で作りデプロイ検証をしたい
ポート番号: 443
環境変数: DBへの接続情報あり(ユーザー、パスワード、ポート番号など)
カスタムドメインの有無: あり

Claude:

● ありがとうございます。重要な情報が揃いました。まず仕様書を更新してから /speckit.plan に進みます。

  いくつか確認させてください:                                                                                                                                                                                                                                   

  ポート 443 について: App Runner でコンテナが直接 443 を listen している構成でしょうか?ECS Express Mode では ALB が 443 を終端し、コンテナへは別ポート(例: 8080)で転送するのが一般的です。コンテナ内ポートが 443 で間違いないか確認させてください。

  環境変数(DB接続情報)について: パスワードなどの機密情報は AWS Secrets Manager または Parameter Store で管理していますか?それとも App Runner の環境変数に直接設定していますか?

  ---                                                                                                                                                                                                                                                            
  この2点が移行計画の設計に大きく影響するため確認しています。もし「App Runner の設定に合わせて作れば良い」ということであれば、サンプルアプリ向けに合理的なデフォルト(コンテナポート 8080、Secrets Manager 使用)で進めることもできます。どうしますか?          

■ 2回目(修正)

私:

ポート番号: コンテナ側 8080
環境変数は AWS Secrets Manager を利用
RDS Serverless の PostgreSQL を利用

Claude:

● 情報が揃いました。仕様書を更新してから /speckit.plan を実行します

  Read 1 file (ctrl+o to expand)

● まず仕様書を最新情報で更新してからプランを実行します。

● Update(specs/001-apprunner-to-ecs-express-migration/spec.md)
  ⎿  Added 6 lines, removed 5 lines
       93
       94  ## Assumptions
       95

~省略~

フォーマットの厳密さは不要で、後から修正・追加しながら要件を固めていく形になります。 Spec Kit が会話内容を整理し、spec.md に反映するので事前に要件定義書を作りこまなくても大丈夫です。

spec.md の作成後は、Spec Kit により plan.md、tasks.md、quickstart.md が順次生成されていきます。

これにより、「何を作るか」だけでなく、「どのように作るか」「どの順番で実施するか」までが整理された状態となります。

最終的に /speckit.implement を実行することで、タスクに基づいた実装および検証が進められます。

移行検証の Step

使用した AWS サービス一覧

サービス 用途
AWS App Runner コンテナアプリのホスティング(移行元)
Amazon ECS Express Mode コンテナアプリのホスティング(移行先)
Amazon Aurora Serverless v2 PostgreSQL データベース
AWS Secrets Manager DB 認証情報の管理
Amazon ECR コンテナイメージの保存
Application Load Balancer ECS Express Mode が自動プロビジョニング
AWS Certificate Manager ワイルドカード証明書(*.任意のドメイン)
Amazon Route 53 カスタムドメイン・加重ルーティング
AWS IAM ecsTaskExecutionRole / ecsInfrastructureRoleForExpressServices など

Spec Kit により整理されたタスクをもとに、実際の構築・検証を以下のステップで実施しています。

  • Step 1: サンプルアプリを作る
  • Step 2: 基盤リソースを構築する
  • Step 3: Route 53 加重ルーティングでトラフィックを段階移行
  • Step 4: クリーンアップ

Step 1: サンプルアプリを作る

今回のアプリは FastAPI で、以下の3つのエンドポイントを持つシンプルな構成です。

@app.get("/")
def root():
    return {"message": "Hello from sample-app", "environment": "ecs-express"}

@app.get("/health")
def health():
    return {"status": "ok", "service": "sample-app"}

@app.get("/db-check")
def db_check():
    creds = get_db_credentials()
    conn = get_db_conn()
    conn.close()
    return {"status": "ok", "db_host": creds["host"], "db_name": creds["dbname"]}

Step 2: 基盤リソースを構築する

再現性を重視し、移行元(App Runner)と移行先(ECS Express Mode)の両方を AWS CLI でスクリプト化されていました。 ただし、実行中にうまくいかないことがあると自動的に修正コマンドを実行してしまい、スクリプトへの反映が漏れしてしまうことが多々ありました。

infra/
  apprunner/
    create-service.sh      # App Runner サービス作成
  ecs-express/
    create-rds.sh          # Aurora Serverless v2 クラスター作成
    create-secrets.sh      # Secrets Manager に DB 認証情報を登録
    create-iam-roles.sh    # ECS 用 IAM ロールを作成
    create-ecr.sh          # ECR リポジトリ作成 + イメージプッシュ
    create-service.sh      # ECS Express Mode サービス作成

Step 3: Route 53 加重ルーティングでトラフィックを段階移行

Route 53 の加重ルーティングを利用し、App Runner から Amazon ECS Express Mode へ段階的にトラフィックを切り替えます。

Spec Kit により生成された tasks.md をもとに Claude Code が traffic-shift.sh といったスクリプトを生成し、Route 53 の change-resource-record-sets を利用して、 App Runner と ECS Express Mode 向けの加重レコードを実施しました。

初回実行時は、既存のシンプルルーティングを削除してから App Runner / ECS Express Mode の加重レコードをまとめて作成します。

各レコードの weight を変更することで、トラフィック比率を段階的に切り替えます。

トラフィック比率は以下のように段階的に切り替えています。

  • App Runner 100% / ECS 0%
  • App Runner 90% / ECS 10%
  • App Runner 75% / ECS 25%
  • App Runner 50% / ECS 50%
  • App Runner 25% / ECS 75%
  • App Runner 0% / ECS 100%

今回は、加重ルーティング中のリクエストが App Runner / ECS のどちらから返されているかを確認するため、server レスポンスヘッダーを確認していました。

curl -sI https://ドメイン名/health | grep server
結果 判別
server: envoy App Runner
server: uvicorn ECS

App Runner は リクエストをコンテナに渡す前に Envoy プロキシを経由しているようで、本検証では server: envoy の値を確認でき、 ECS(ALB 経由)は ALB が server ヘッダーを書き換えないため、アプリケーション(Uvicorn)の値が確認できました。

切り替え中にこのコマンド定期的に実行すると、大体比率に応じてenvoyuvicorn が混在して返ってくるのを確認できます。 ECS 100% への移行が完了すると server: uvicorn だけが返るようになります。

この方法は環境やアプリケーション構成に依存するため、アプリケーション側で識別用の値(レスポンスヘッダーやボディ)を付与する方法もあります。 用途に応じて確認方法やコマンドを調整する場合は、Claude Code に指示して生成・修正してみてください。

また、実際の移行では、CloudWatch の 5xx エラーなどのメトリクスを併用して確認することを推奨します。

Step 4: クリーンアップ

削除コマンドについても Spec Kit のタスクをもとに、Claude Code により自動生成されていました。
削除処理は冪等性を考慮して実装されており、すでに削除済みのリソースはスキップされるようになっています。

また、ALB や RDS など削除に時間がかかるリソースについては、削除完了まで待機する処理も含まれていました。

※ 本スクリプトは削除処理を行うため、実行前に内容を確認したうえで実行するほうが無難です。

失敗談

カスタムドメイン + HTTPS を設定忘れ

加重ルーティング開始後に ECS 側へトラフィックが流れたタイミングで、接続エラーが発生していました。 今回の検証ではカスタムドメインありでの構成を前提としていましたが、ECS 側のカスタムドメイン + HTTPS の設定を忘れていたのが原因でした。

Claude によると、 ECS Express Mode ではデフォルトドメイン(*.ecs.ap-northeast-1.on.aws)であれば正常に動作したため、カスタムドメインの設定を忘れていたという回答ありました。

ECS Express Mode が作成する ALB にはデフォルト証明書のみ設定されているため、カスタムドメイン対応には以下の設定が必要であることを伝えして、実装してもらいました。

  1. カスタムドメインの host-header ルールを追加
  2. ACM 証明書を HTTPS リスナーに追加(事前に証明書を発行しておく必要あり)

参考:AWS のドキュメントでは「ステップ 3: ECS Express Mode のカスタムドメインを設定する」

意図しないパブリックサブネットの作成

初期の検証では、パブリックサブネットが1つのみの VPC で構築を進めようとしていました。 ECS Express Mode の要件としてパブリックサブネットが2つ以上(ALBで利用)が必要であるため、エラーとなりました。

その時、Claude Code が自動的に追加のパブリックサブネットを作成する処理を実行しており、意図しないリソースが作成される形となっていました。インフラ構成の前提条件については事前に人間で確認しておく方がいいと思います。

docs.aws.amazon.com

Claude:

ECS Express Mode には同一タイプのサブネットが2つ必要です。
パブリックサブネットを ap-northeast-1c にも追加します。

~省略~

私(焦っている):

うぉーい! 作成したんですか?
vpc-aaaaaaaaaaaaaa やっぱりこっちのVPCにしてほしい
snsubnet-bbbbbbbbbb、subnet-cccccccccccc のサブネットを利用して
作成したものサブネットとかは消して下さい

Claude(冷静):

VPC を変更します。新しい VPC の詳細を確認してから対応します。

~省略~

改善ポイント(IaC 化による再現性の担保)

今回の検証では AWS CLI ベースでスクリプト化していたため、以下のような問題が発生していました。

  • リソース再作成時の ID / ARN の変更による不整合

これらは Claude Code による個別修正で対応は可能ですが、本質的には「冪等性」と「再現性」の問題です。

今回の検証を通じて、AWS CLI ベースのスクリプトで実装した内容は、検証後(または検証と並行して)CDK などの IaC ツールへ変換することで、以下の点を改善できると感じました。

  • リソース間の参照を論理的に管理できる
  • 再実行時の差分適用が自動化される
  • ID / ARN の変化を意識する必要がなくなる

このように IaC 化することで、検証環境で構築した内容をベースに、移行先である Amazon ECS Express Mode の構成を再現性を保ったまま展開できると考えています。

まとめ

AWS App Runner から Amazon ECS Express Mode への移行を Claude Code と Spec Kit を組み合わせた移行検証を行いました。

要件の言語化から実装まで AI と人間が対話しながら整理・修正し進められる開発スタイルをインフラ面(仕様駆動型のインフラ開発)でも活用できることを実感しました。

  • 要件の言語化から仕様定義~実装までの一貫した流れの自動化
  • 実行・修正を繰り返しながらその場で動作確認できる検証のしやすさ
  • 実行結果をもとにスクリプトをその場で修正・更新できる開発体験

特にインフラ構築・検証においては、IaC(CDK など)を実装しない限り、「AIが実行した内容」と「再実行可能なコード」が一致しない状態となりやすく再現性の担保が課題になります。

アプリケーション開発のようにコードが正とならず、実環境の状態にも依存するのでこの差分をどのように管理・前提とするかがポイントになりそうです。 また、会話履歴のみでは構成情報が完全に保持されるわけではないため、その点も考慮が必要です。

  • 実行内容が必ずしもコードに反映されない
  • インフラ構成の前提条件が暗黙的になりやすい
  • 再現性(冪等性)の担保には追加の設計が必要

まずは AWS CLI ベースで素早く検証を行い、その結果をもとに IaC 化していくアプローチは、生成AIを活用した開発スタイルになっていくのではないかと個人的に感じました。

本記事が、Claude Code や Spec Kit を活用したインフラ面での開発・検証の参考になれば幸いです。

近藤 諒都

(記事一覧)

カスタマーサクセス部CS5課

夜行性ではありません。朝活派です。

趣味:お酒、旅行、バスケ、掃除、家庭用パン作り(ピザも)など

2025 Japan AWS All Certifications Engineers