- 1 1. 簡易コンテナデプロイの本番課題とApp Runnerの全体像
- 2 2. App Runner基礎 — ソースコード/イメージデプロイとサービス設定
- 3 3. オートスケール&リソース設定
- 4 4. ネットワーキング — VPCコネクタ・プライベートサービス・カスタムドメイン
- 5 5. CI/CD・運用
- 6 6. セキュリティ・コスト
- 7 7. 実戦統合パターン — ECS/EKS/Lambdaとの使い分け
- 8 8. つまずきポイント・アンチパターン・まとめ
1. 簡易コンテナデプロイの本番課題とApp Runnerの全体像

コンテナを本番で動かすまでの「運用の壁」
コンテナアプリケーションを本番環境で稼働させるには、多くの準備が必要です。ECSやEKSでのクラスター設計、Application Load Balancerの構築、セキュリティグループとIAMポリシーの設定、オートスケーリングポリシーの調整、TLS証明書の取得と更新、CloudWatchアラームの整備——これらはすべて、アプリケーションのビジネスロジックとは直接関係のない運用作業です。
小規模なWebサービスやAPIを素早く本番公開したい場合、このインフラ整備にかかる時間とコストがサービス開発のボトルネックになりがちです。AWSインフラ専任者がいない開発チームにとって、このハードルはさらに高くなります。
「コンテナアプリは動かしたいが、インフラ管理の負担は最小化したい」——このニーズに応えるのが AWS App Runner です。
AWS App Runnerとは何か
AWS App Runnerは、ソースコードまたはコンテナイメージを渡すだけで、ビルド・デプロイ・ロードバランシング・オートスケール・TLS証明書の取得まで、一切のインフラ管理をAWSが代行するフルマネージドコンテナサービスです。
2021年にGAとなり、現在も現役で活発に機能追加が続いています。VPCコネクタによるプライベートリソースへの接続、プライベートサービス(インバウンド制限)、AWS WAF連携、X-Rayトレーシング対応など、本番ユースケースに必要な機能が着実に追加されてきました。
開発者がApp Runnerで行う作業はシンプルです。
- ソースコードデプロイ: GitHubリポジトリと連携し、
apprunner.yamlでビルド・起動コマンドを定義する - イメージデプロイ: Amazon ECRにDockerイメージをプッシュし、そのURIをApp Runnerに指定する
どちらの方式でも、数分のうちにHTTPS付きのURLが発行され、アプリケーションが公開されます。ALBの設定、DNS設定、ACM証明書のアタッチ——これらはApp Runnerが自動で処理します。
デプロイ2方式の概要
App Runnerには2つのデプロイ方式があります。チームの技術スタックやCI/CDの成熟度に応じて選択できます。
①ソースコードデプロイ
GitHubリポジトリ(またはAWS CodeCommit)と連携し、指定ブランチへのpushを検知するとApp Runnerが自動でビルドを実行します。ビルド設定はリポジトリのルートに置いた apprunner.yaml で定義します。
対応しているマネージドランタイムはPython・Node.js・Java・Go・PHPなど複数あります(最新のサポート状況はAWSドキュメントで確認してください。ランタイムバージョンは随時更新されます)。
ビルド中はビルドフィーが発生します。ビルド時間に応じたvCPUとメモリの課金です。Dockerfileを用意しなくてもデプロイできる点が大きな利点で、インフラ経験が浅いチームでもコンテナデプロイを実現できます。
②コンテナイメージデプロイ
Amazon ECRのプライベートリポジトリ、またはECR Publicのコンテナイメージを指定してデプロイします。ECRにイメージがプッシュされた際に自動デプロイを行う設定も可能で、既存のCI/CDパイプライン(GitHub Actions・AWS CodePipeline等)で構築したイメージをそのままApp Runnerで実行できます。
Dockerfileで細かくイメージを制御したい場合、複数のランタイムが混在する場合、またはマルチステージビルドで最適化したイメージを使いたい場合は、イメージデプロイが適しています。
同時実行ベースのオートスケールとプロビジョンドインスタンス
App Runnerのオートスケールは同時実行(concurrency)ベースという独自方式です。
一般的なCPU/メモリベースのオートスケールとは異なり、「1インスタンスあたりの最大同時リクエスト数(Max Concurrency)」というしきい値を設定します。受信中のリクエスト数がこの値を超えると、App Runnerが自動で新しいインスタンスを追加します。
例えば、Max Concurrencyを100に設定した場合、受信中のリクエスト数が100に達した時点でインスタンスが追加されます。CPUやメモリ使用率ではなくリクエスト数でスケールするため、バースト的なトラフィックにも即応できます。
プロビジョンドインスタンスによるコールドスタート対策
スケールインでアイドル状態になったインスタンスは即座に終了するのではなく、プロビジョンドインスタンス(CPUスロットル状態)へと縮退します。プロビジョンドインスタンスはメモリ上のアプリケーション状態を保持しつつ、CPUはスロットルされてコストを削減します。
次にリクエストが届いた際は、コールドスタートを経ることなくミリ秒単位で応答を再開できます。この仕組みにより、スパイクトラフィックへの耐性を確保しつつ、コールドスタートレイテンシの影響も最小化されています。
プロビジョンドインスタンスはアイドル中もメモリGB課金が発生するため、最小インスタンス数の設定がコスト管理の重要なパラメーターとなります(詳細は§6で解説します)。
コンテナ実行サービスの抽象度と使い分け
AWSにはコンテナ関連サービスが複数あり、抽象度によって使い分けが決まります。
| サービス | 抽象度 | 主な管理責任 | 向くケース |
|---|---|---|---|
| EC2 | 低 | OS・ミドルウェア・スケーリング全般 | インフラを完全制御したい |
| ECS / EKS on Fargate | 中 | タスク定義・サービス・ネットワーク設定 | クラスター管理は省略したいが細かな制御が要る |
| AWS Lambda | 高 | 関数コードのみ | イベント駆動・短時間処理・関数単位 |
| App Runner | 最高 | アプリコードまたはイメージのみ | コンテナのURL公開を最速・最小運用で |
App Runnerは「コンテナを素早くWeb公開したい、かつインフラ管理は最小化したい」という要件に最も特化したサービスです。
一方、複雑なネットワーク設計(サイドカーコンテナ・複数のターゲットグループ等)、精密なスケール制御、バッチ処理・長時間実行、Kubernetes標準エコシステムの活用が必要な場合はECS/EKSが適しています。この使い分けの詳細なフローチャートは§7で整理します。
本記事(Vol1)の構成と想定読者
本記事では、App Runnerを本番で安定稼働させるために必要な知識を以下の流れで解説します。
- §2: App Runnerの基礎——デプロイ2方式のサービス設定と
apprunner.yaml - §3: オートスケール&リソース設定——同時実行ベースのスケール設計とvCPU/メモリ選択
- §4: ネットワーキング——VPCコネクタ・プライベートサービス・カスタムドメイン/TLS
- §5: CI/CD・運用——自動デプロイ/ロールバック・CloudWatch・X-Rayトレーシング
- §6: セキュリティ・コスト——IAMロール設計とコスト3要素の最適化
- §7: ECS/EKS/Lambdaとの使い分けフローチャート
- §8: つまずきポイント・アンチパターン・まとめ
想定読者
- コンテナアプリを本番公開したいが、ECS/EKSの複雑さを避けたい開発者・チーム
- AWSインフラ専任者なしで、小〜中規模のWebサービス・APIを本番展開したい方
- App Runnerのオートスケール・VPCコネクタ・コスト構造を実践的に理解したい方
- ECS/EKS・LambdaとApp Runnerの使い分けを整理したい方
AWSのEC2・S3・VPCの基本概念を把握していることを前提とします。ECS/EKSの詳細な経験は不要で、App Runner独自の概念から順を追って解説します。
- App Runner基礎 — ソースコード/イメージデプロイ・自動ビルド・サービス設定(§2)
- オートスケール&リソース設定 — 同時実行ベーススケール・vCPU/メモリ・シークレット連携(§3)
- ネットワーキング — VPCコネクタ・プライベートサービス・カスタムドメイン/TLS(§4)
- CI/CD・運用 — 自動デプロイ/ロールバック・監視/ログ/トレース(§5)
- セキュリティ・コストと、ECS/EKS/Lambdaとの使い分け(§6・§7)
- App Runner — ソース/イメージからURL公開まで全自動。インフラ・クラスター管理不要(本記事)
- ECS/EKS — オーケストレーション制御重視。細かな制御・大規模・複雑構成に最適(既存コンテナシリーズ)
- Lambda — 関数単位・イベント駆動(既存サーバーレス記事)
- EC2 — インフラ自前管理(既存Compute記事)。本記事はApp Runnerの本番運用に集中
細かな制御が要るならこちら(コンテナ本番運用 Vol1 — ECS/Fargate/ECR)
2. App Runner基礎 — ソースコード/イメージデプロイとサービス設定

App Runnerの起点はシンプルです。「どこからコードやイメージを取得するか」を指定するだけで、ビルド・デプロイ・ロードバランシング・TLS証明書の発行まですべてが自動実行されます。デプロイ方式にはソースコードデプロイとコンテナイメージデプロイの2種類があり、用途に応じて使い分けます。
2-1. ソースコードデプロイ — GitHub/Bitbucket連携と自動ビルド
ソースコードデプロイは、GitHubまたはBitbucketのリポジトリをApp Runnerに直接連携する方式です。コードをpushするたびに、App Runnerが自動的にビルドを実行し、新しいリビジョンとしてデプロイします。インフラ側での追加設定なしに、リポジトリへのpushだけで本番更新を完結できるのが最大のメリットです。
apprunner.yaml — ビルドとランタイムの定義
ビルド・ランタイム・起動コマンドはリポジトリルートに置くapprunner.yamlで定義します。
version: 1.0
runtime: python311
build:
commands:
pre-build:
- pip install -r requirements.txt
build:
- echo "Build phase"
run:
command: uvicorn main:app --host 0.0.0.0 --port 8080
network:
port: 8080
env:
- name: STAGE
value: production
主要な設定フィールドを確認します。
| フィールド | 説明 |
|---|---|
runtime | マネージドランタイム(python311/nodejs20/java21/go1等) |
build.commands.pre-build | 依存パッケージのインストール等 |
build.commands.build | ビルドコマンド本体 |
run.command | アプリの起動コマンド(startCommand相当) |
run.network.port | アプリがリッスンするポート番号 |
run.env | 環境変数の静的設定 |
ビルドフィーに注意: ソースコードデプロイでは、App Runnerがビルドを実行するため、ビルド時間に応じたコストが発生します。ビルドが長時間かかるプロジェクトや本番規模では、後述のコンテナイメージデプロイへの切り替えも検討してください。
GitHub連携の設定
AWSコンソールでサービスを作成する際は次の手順で連携します。
- ソースリポジトリタイプとして「Source code repository」を選択します
- 「Connect to GitHub」をクリックし、GitHub App経由でApp Runnerに認証権限を付与します
- 対象リポジトリとブランチを選択します
- デプロイトリガーを「Automatic」(pushで自動デプロイ)または「Manual」(手動のみ)から選択します
CLIでの作成例を示します。
aws apprunner create-service \
--service-name my-api \
--source-configuration '{
"CodeRepository": {
"RepositoryUrl": "https://github.com/myorg/my-api",
"SourceCodeVersion": {
"Type": "BRANCH",
"Value": "main"
},
"CodeConfiguration": {
"ConfigurationSource": "REPOSITORY"
}
},
"AutoDeploymentsEnabled": true
}' \
--instance-configuration '{"Cpu": "1 vCPU", "Memory": "2 GB"}'
ConfigurationSourceをREPOSITORYにするとapprunner.yamlの設定が使われ、APIにするとCLI/コンソールの設定が優先されます。大規模プロジェクトではREPOSITORYでコードと設定を一元管理するのが推奨です。
2-2. コンテナイメージデプロイ — ECR連携
コンテナイメージデプロイは、Amazon ECRに格納したコンテナイメージをApp Runnerに渡す方式です。ビルドはCI/CDパイプライン(GitHub ActionsやCodeBuild等)側で行い、App RunnerはECRからイメージをPullしてデプロイするだけです。
アクセスロールの設定
ECRプライベートリポジトリを使う場合、App RunnerがイメージをPullするためのアクセスロールが必要です。アプリがS3やDynamoDBなど他のAWSサービスを呼ぶインスタンスロールとは別物なので、混同しないように注意してください。
アクセスロールに付与するポリシー例を示します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:DescribeImages",
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability"
],
"Resource": "*"
}
]
}
信頼ポリシーにはbuild.apprunner.amazonaws.comを指定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "build.apprunner.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
イメージデプロイのCLI例
aws apprunner create-service \
--service-name my-api-image \
--source-configuration '{
"ImageRepository": {
"ImageIdentifier": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-api:latest",
"ImageRepositoryType": "ECR",
"ImageConfiguration": {
"Port": "8080",
"RuntimeEnvironmentVariables": {
"STAGE": "production"
}
}
},
"AuthenticationConfiguration": {
"AccessRoleArn": "arn:aws:iam::123456789012:role/AppRunnerECRAccessRole"
},
"AutoDeploymentsEnabled": true
}' \
--instance-configuration '{"Cpu": "1 vCPU", "Memory": "2 GB"}'
AutoDeploymentsEnabled: trueに設定すると、ECRのlatestタグが更新されたタイミングで自動デプロイが走ります。本番環境では、latestではなくコミットSHAやバージョン番号をタグに使い、イメージの追跡を明確にするのがベストプラクティスです。
2-3. ソースコードデプロイ vs コンテナイメージデプロイ 比較
2方式の特性を比較します。
| 観点 | ソースコードデプロイ | コンテナイメージデプロイ |
|---|---|---|
| ビルド場所 | App Runner側(自動) | CI/CDパイプライン側 |
| ビルドフィー | 発生 | 発生しない |
| デプロイ速度 | ビルド時間分遅い | 速い(イメージPullのみ) |
| 柔軟性 | マネージドランタイムに依存 | Dockerfileで自由に構成 |
| 本番適性 | 軽量・プロトタイプ向き | 本番・複雑な依存関係向き |
| 自動デプロイトリガー | Gitブランチpush | ECRイメージ更新 |
実運用ではコンテナイメージデプロイを推奨します。ビルドはGitHub ActionsやCodeBuildで行い、ECRにpushするCI/CDパイプラインを組み合わせると、ビルドコストの削減と再現性の向上を両立できます。
2-4. サービス設定の主要項目
App Runnerサービス作成・更新時に設定する主要項目を整理します。
| 設定項目 | 説明 | 備考 |
|---|---|---|
| ポート | アプリがリッスンするポート番号 | デフォルト8080 |
| 環境変数 | 平文の環境変数 | コンソール/YAML/CLIで設定 |
| シークレット参照 | Secrets Manager/SSMパラメータストア | §3で詳述 |
| CPU | 0.25/0.5/1/2/4 vCPU | インスタンス単位で課金 |
| メモリ | 0.5〜12 GB(CPUとの組合せに制約あり) | メモリはプロビジョンド課金にも影響 |
| ヘルスチェック | HTTP(パス指定)またはTCP | デプロイ成功判定の要 |
| デプロイタイプ | Automatic/Manual | 本番はManual推奨の場合も |
ポート設定はアプリのリッスンポートと必ず一致させてください。不一致の場合、ヘルスチェックに失敗してデプロイはロールバックされます。
2-5. リビジョン管理
App Runnerはデプロイごとに新しいリビジョンを作成します。コンソールのリビジョン一覧から過去の構成を確認でき、前のリビジョンへの手動ロールバックも可能です。
リビジョン管理のポイントを押さえておきます。
- 各リビジョンはソースのコミットSHAまたはイメージダイジェストを記録します
- 環境変数・リソース設定の変更もリビジョンに紐づいて保存されます
- 手動ロールバックは「以前のリビジョンを再デプロイ」扱いで、新しいリビジョンIDが払い出されます
- デプロイ失敗時の自動ロールバックと手動ロールバックは独立した機能です
- ソースコードデプロイ — GitHub等から自動ビルド(apprunner.yamlでランタイム/ビルド設定・ビルドフィー発生)
- コンテナイメージデプロイ — ECRのイメージを直接デプロイ
- サービス設定 — ポート/環境変数/起動コマンド。App Runnerが自動でビルド→デプロイ→TLS付きURL発行
- リビジョン管理で構成変更・デプロイ履歴を追跡
3. オートスケール&リソース設定

App Runnerのオートスケールは、ECSやEKSとは根本的に異なる「同時実行ベース(concurrency-based)」の仕組みを採用しています。この特性を正しく理解することが、本番環境での安定稼働とコスト最適化の出発点となります。
同時実行ベースオートスケールの仕組み
App Runnerは1つのインスタンス(コンテナ)が同時に処理できるリクエスト数(MaxConcurrency)を設定し、そのしきい値を超えると新しいインスタンスを起動してスケールアウトします。例えばMaxConcurrencyを25に設定した場合、1インスタンスで25リクエストを同時に処理している状態でさらなるリクエストが届くと、追加インスタンスの起動が始まります。
この仕組みはECSのService Auto ScalingでCPU使用率やメモリ使用率をメトリクスとしてスケールする「タスクベーススケール」とは大きく異なります。ECSタスクベーススケールでは、CPU・メモリ使用率が一定しきい値を超えるとCloudWatchアラームを発火させてスケーリングポリシーを動かすため、数十秒から数分の反応遅延は発生します。
一方App Runnerの同時実行ベーススケールは、リクエストキューへの蓄積を検知して即座にインスタンス追加を判断するため、急激なトラフィックスパイクに対しても素早く対応できます。ただし、スケールアウトに要する時間(新インスタンスの起動時間)は数秒から十数秒ある点に注意が必要です。瞬時の大量アクセスへの対策として、最小インスタンス数(MinSize)を事前に調整することが重要です。
ECSタスクベーススケールとの主要な違い
| 比較軸 | App Runner(同時実行ベース) | ECS(タスクベース) |
|---|---|---|
| スケールトリガー | 同時リクエスト数 | CPU/メモリ使用率・カスタムメトリクス |
| 反応速度 | 即時(キュー蓄積を直接検知) | CloudWatchアラーム経由(数十秒〜数分) |
| 設定の複雑さ | 低(MaxConcurrency/Min/Max) | 中〜高(スケーリングポリシー・ターゲット追跡など) |
| チューニング項目 | MaxConcurrency、Min/MaxSize | スケーリングポリシー種別・クールダウン期間など |
| 予測スケーリング | 非対応 | Application Auto Scaling経由で対応可 |
App Runnerの同時実行ベーススケールはシンプルな分、ECSのような「急激なスパイク前に予測スケール」や「SQSキュー深度をトリガーにしたスケール」などの高度なシナリオには対応していません。そういった要件がある場合はECSの利用を検討してください。
Auto Scaling Configurationの設定項目
Auto Scaling Configurationは独立したリソースとして作成・管理でき、複数のApp Runnerサービスで共有できます。主要な設定項目は以下の3つです。
MaxConcurrency(最大同時実行数)
1インスタンスが同時に受け付けるリクエスト数の上限です。設定範囲は1〜200です。この値は「インスタンスを追加するトリガー」であり、アプリケーションの処理特性に合わせて調整します。
- I/O待機が多いWebアプリ(DBクエリ待ち・外部API呼び出し): 50〜100程度に設定するとリソースを効率利用できます
- CPU処理が重いエンドポイント(画像処理・暗号化など): 1〜10程度に下げてインスタンスの早めの追加を促します
- 軽量なAPIゲートウェイ的用途: 100〜200に設定してインスタンス数を抑えます
MaxConcurrencyはクラスター・サービスレベルの概念がなく、コンテナ1台あたりの同時接続数で直接スケールを制御するため、ECSのような複雑なスケーリングポリシー設定が不要です。
MinSize(最小インスタンス数)
常時起動しておくインスタンスの下限数です。デフォルトは1です。
- MinSize=1(デフォルト): 常に1インスタンス以上が稼働します。プロビジョンドインスタンスとしてコールドスタートを回避できますが、アイドル時もインスタンス費用は発生します
- MinSize=0(オプション): 完全なゼロスケールが可能です。リクエストゼロ時は課金なし。ただし初回リクエスト時にはインスタンス起動を要するため、コールドスタートレイテンシが発生します(数秒〜十数秒程度)
本番環境のAPIサービスでは応答遅延を避けるためMinSize=1を推奨します。ステージング環境・社内ツールなど応答速度が厳しくない場合はMinSize=0でコスト削減を検討できます。
MaxSize(最大インスタンス数)
スケールアウトできるインスタンス数の上限です。デフォルトは25で、最大200まで設定できます。
MaxSizeはコスト上限制御として極めて重要な設定です。バグや攻撃によるリクエスト急増が起きても、MaxSizeを超えたインスタンス追加は発生しません。トラフィックスパイク対策としてMaxSizeを大きくしすぎると、インシデント時の費用が膨らみかねません。本番設定では期待する最大トラフィックを算定し、意図的な上限を設けることをお勧めします。
プロビジョンドインスタンスとアイドル縮退の仕組み
App Runnerにはリクエストがない(アイドル状態の)インスタンスを「プロビジョンドインスタンス」として維持する仕組みがあります。プロビジョンドインスタンスはCPUをスロットル(制限)した状態で待機しますが、メモリは保持されたままです。
リクエストが届くとミリ秒単位でアクティブ状態に復帰するため、コールドスタートなしに応答できます。プロビジョンドインスタンス状態ではvCPUの課金が停止し、メモリのみの課金(プロビジョンドインスタンス料金)となります。
この仕組みにより次の効果が得られます:
- アイドル時のコストをアクティブ時の20〜30%程度に削減できます
- MinSize=1を維持しながらコールドスタートを回避できます
- スケールイン(インスタンス削減)も自動的にプロビジョンド状態を経由して行われます
アイドルからアクティブへの復帰はミリ秒単位ですが、スケールアウト(新規インスタンス起動)は数秒〜十数秒かかります。「アイドルからの復帰」と「新規インスタンス追加」を混同しないよう注意してください。
vCPU・メモリの選定基準
App RunnerはvCPUとメモリのペアを事前定義された組み合わせから選択します。以下は代表的な組み合わせです(最新の選択肢はAWSコンソールまたは公式ドキュメントで確認してください)。
| vCPU | メモリ | 用途例 |
|---|---|---|
| 0.25 vCPU | 0.5 GB | 軽量APIサーバー・静的コンテンツ配信 |
| 0.5 vCPU | 1 GB | 小〜中規模Webアプリの初期設定 |
| 1 vCPU | 2 GB | 標準的なWebアプリ・REST API |
| 2 vCPU | 4 GB | 中規模・画像処理・機械学習推論API |
| 4 vCPU | 8 GB | 大規模処理・高スループットAPI |
| 4 vCPU | 12 GB | メモリ集約型ワークロード |
まず小さく始めて観測する
0.5 vCPU/1 GBなど小さいサイズから始め、CloudWatchのCPU使用率・メモリ使用量を監視して、ボトルネックに応じてサイズを拡張します。スペックを大きくしてもインスタンス起動時間やMaxConcurrencyの特性は変わらないため、段階的な検証が安全です。
メモリ不足の兆候を見逃さない
コンテナが頻繁に再起動する・OOMKilledログが出る・特定のリクエスト処理後にレイテンシが高止まりする場合は、メモリ不足を疑います。Node.jsやJava系のランタイムはヒープ設定によってメモリを多く消費するため、コンテナのメモリ設定(NODE_OPTIONS=–max-old-space-size= など)とApp Runnerのメモリ設定の整合性を確認してください。
CPU最適化が必要なケース
画像変換・動画サムネイル生成・暗号化・圧縮など演算負荷の高い処理を多用する場合は、vCPUを優先して選択します。これらの処理はI/O待ちではなくCPU時間を消費するため、MaxConcurrencyを小さくしてもCPU使用率は高くなる傾向にあります。
コストとのトレードオフ
vCPU・メモリが大きいほどアクティブインスタンスの単価が上がります。「インスタンス数 × 単価」がランニングコストを決めるため、MaxConcurrencyとの組み合わせで最適化します。例えば同じスループットを達成するのに、小さいインスタンスを多数起動するパターンと大きいインスタンスを少数起動するパターンではコストが異なります。負荷テストで両者を比較することをお勧めします。
Auto Scaling ConfigurationのCLI管理
Auto Scaling ConfigurationはARNとバージョンで管理されます。設定変更後に新しいバージョンを作成し、サービスに明示的に関連付けることで反映されます。
aws apprunner create-auto-scaling-configuration \
--auto-scaling-configuration-name "production-config" \
--max-concurrency 50 \
--min-size 2 \
--max-size 20
aws apprunner update-service \
--service-arn arn:aws:apprunner:ap-northeast-1:123456789012:service/myapp/xxxxx \
--auto-scaling-configuration-arn \
arn:aws:apprunner:ap-northeast-1:123456789012:autoscalingconfiguration/production-config/1/xxxxx
環境変数の設定
タイムゾーン・アプリ環境名・ログレベルなど平文で設定して問題ない値は、環境変数として直接設定できます。ソースコードデプロイ時は apprunner.yaml の run.env セクションでも設定できます。
シークレット管理(Secrets Manager / SSM Parameter Store連携)
データベースパスワード・APIキー・接続文字列など機密情報は、平文の環境変数として設定することを避け、AWS Secrets ManagerまたはSSM Parameter Storeを利用します。
AWS Secrets Managerとの連携手順
- Secrets ManagerにシークレットをJSON形式で保存します
- App RunnerサービスのIAMロール(インスタンスロール)にシークレットの読み取り権限(
secretsmanager:GetSecretValue)を付与します - サービス設定のEnvironment VariablesでシークレットARNを指定します
コンテナ起動時に自動的に環境変数として注入されるため、アプリケーション側での特別な実装は不要です。
SSM Parameter Storeとの連携手順
- Parameter Storeに文字列(String)または暗号化文字列(SecureString)としてパラメータを保存します
- インスタンスロールに
ssm:GetParameters権限を付与します - App RunnerサービスのEnvironment Variablesでシークレット参照として指定します
シークレット連携の主なメリットは次のとおりです:
- ソースコードや設定ファイルに機密情報が残りません
- シークレットのローテーション(自動更新)をアプリケーション変更なしに実施できます
- IAMポリシーでシークレットへのアクセスを一元管理できます
- Secrets Managerの自動ローテーション機能と組み合わせることでDBパスワードの定期変更を自動化できます
スケール設定とコストの関係整理
§6で詳述しますが、スケール設定はコストに直結するため、設計意図を事前に整理しておくことが重要です。
| 設定項目 | コスト影響 | 推奨アプローチ |
|---|---|---|
| MinSize | 常時コストの下限(MinSize×プロビジョンド料金) | 本番=1以上、非本番=0を検討 |
| MaxSize | 突発スパイク時のコスト上限 | 期待最大トラフィックの1.5〜2倍を上限に |
| MaxConcurrency | 低いほど多くのインスタンスが起動しやすい | 処理特性に応じて25〜100を目安に |
| vCPU/Memory | インスタンス単価を決定 | 負荷テストで最小必要スペックを確認 |
これらの設定を適切に組み合わせることで、レイテンシ要件を満たしながらコストを最適化できます。設定変更はApp Runnerサービスの更新として即時反映されますが、新しいインスタンスに適用されるのは次の起動タイミングとなります。既存の稼働中インスタンスには即時反映されない点に注意してください。
- ★同時実行(concurrency)ベース — 1インスタンスの同時リクエスト数しきい値超過でインスタンス追加
- アイドル時はプロビジョンドインスタンス(CPUスロットル)へ縮退しコスト削減(ミリ秒で応答再開)
- Auto Scaling Configurationで最小/最大インスタンス数を設定。最大数でコスト上限制御
- vCPU/メモリ組合せ選択。環境変数・シークレット(Secrets Manager/SSM)連携
4. ネットワーキング — VPCコネクタ・プライベートサービス・カスタムドメイン

App Runnerはデフォルトでパブリックインターネットに向けてのみ通信します。ただし本番システムではRDS・ElastiCache・OpenSearch等のプライベートリソースへ安全に接続する必要があります。この要件に応えるのがVPCコネクタです。同時に、外部からApp Runnerサービスへのアクセスを自社VPC内に限定するためのプライベートサービス機能と、エンドユーザー向けのカスタムドメイン+TLS自動管理も本節で解説します。
4-1. VPCコネクタの仕組みとアーキテクチャ
VPCコネクタはApp RunnerとユーザーVPCをつなぐネットワーク橋渡し機構です。内部的にはAWS Hyperplane(AWSが自社基盤で使用するネットワーク仮想化レイヤ)を利用してApp Runnerのマネージド基盤から指定サブネットへENI(Elastic Network Interface)を注入します。このENIを通じてApp Runnerのコンテナインスタンスがプライベートサブネット上のリソースに直接到達できます。
アウトバウンド方向の接続(App Runner → VPC内リソース)を担うのがVPCコネクタです。これはインバウンド方向(外部 → App Runnerサービス)とは独立した仕組みであり、両方向を混同しないことが設計上の重要ポイントです。
[App Runnerコンテナ] ─→ VPCコネクタ(ENI) ─→ プライベートサブネット ─→ RDS/ElastiCache
│ アウトバウンドのみ
└ SG: App Runnerから許可
インバウンド制限(外部 → サービスへのアクセスをVPC内に限定)は、別途「プライベートサービス」を設定します(4-4節参照)。
4-2. VPCコネクタの作成手順
VPCコネクタはApp Runnerサービスとは独立したリソースとして作成し、複数のサービスから共有できます。
作成時に指定する主要項目
| 項目 | 内容 |
|---|---|
| VPC | App Runnerから接続したいリソースが属するVPC |
| サブネット | プライベートサブネットを2つ以上指定(AZ冗長推奨) |
| セキュリティグループ | VPCコネクタのENIに付与するSG。アウトバウンドを許可する内容にする |
セキュリティグループの設計ポイント
VPCコネクタに付与するSGはアウトバウンドルールが重要です。RDSへのアクセスであればポート3306(MySQL)または5432(PostgreSQL)へのアウトバウンドを許可します。同時に、接続先リソース(RDS・ElastiCacheなど)のSGのインバウンドルールで、VPCコネクタのSGをソースとして許可する設定が必要です。
# VPCコネクタSG(アウトバウンド許可)
Outbound: TCP 3306 → RDS-SG
Outbound: TCP 6379 → ElastiCache-SG
# RDS側SG(インバウンド許可)
Inbound: TCP 3306 ← VPCコネクタSG
この「SGのソースにSGを指定する」パターンにより、IPアドレスによる管理より柔軟かつ安全にアクセス制御できます。
★初回作成2〜5分の待機
VPCコネクタを初めて作成する際、ENIのプロビジョニングに2〜5分かかります。作成リクエスト送信後すぐにActive状態にはならないため、App Runnerサービスへの紐付けは作成完了後に行うことが重要です。CI/CDパイプラインやInfrastructure as Code(Terraform/CDK)でVPCコネクタを自動作成する場合は、ステータスがACTIVEになるまでポーリングするか、aws apprunner describe-vpc-connectorでステータス確認してから次のステップへ進むよう設計してください。
# VPCコネクタ作成
aws apprunner create-vpc-connector \
--vpc-connector-name "my-vpc-connector" \
--subnets subnet-aaaa subnet-bbbb \
--security-groups sg-xxxx
# ステータス確認(ACTIVEになるまで待機)
aws apprunner describe-vpc-connector \
--vpc-connector-arn arn:aws:apprunner:ap-northeast-1:ACCOUNT:vpcconnector/...
4-3. App RunnerサービスへのVPCコネクタ紐付け
VPCコネクタがACTIVE状態になったら、App Runnerサービスのネットワーク設定でアウトバウンドトラフィックの送信先として紐付けます。コンソールではサービス作成時または設定変更(Configurationタブ → Networking)から行えます。
# サービス作成時にVPCコネクタを指定
aws apprunner create-service \
--service-name "my-service" \
--source-configuration '...' \
--network-configuration '{
"EgressConfiguration": {
"EgressType": "VPC",
"VpcConnectorArn": "arn:aws:apprunner:ap-northeast-1:ACCOUNT:vpcconnector/..."
}
}'
EgressTypeをVPCにするとVPCコネクタ経由になり、Default(デフォルト)ではApp RunnerのパブリックNAT経由になります。
既存サービスへの後付けも可能で、設定変更後に再デプロイが走ります。
4-4. プライベートアクセスの対象サービスとセキュリティ設計
VPCコネクタが有効になると、App Runnerからのアウトバウンド通信すべてがVPC経由になります。プライベートVPC内の代表的な接続先を以下に示します。
RDS(Aurora/MySQL/PostgreSQL)
最も一般的なユースケースです。RDSインスタンスのSGでVPCコネクタSGをソースとして許可し、接続文字列はSecrets ManagerまたはSSM Parameter Storeから取得します。App Runnerのインスタンスロール(IAMロール)にSecretsManagerへのアクセス権限を付与しておきます。
ElastiCache(Redis/Valkey)
セッション管理やキャッシュ用途。ElastiCacheのSGでポート6379(Redis)のインバウンドをVPCコネクタSGから許可します。クラスターモード・TLS有効の場合はポート6380を使用するケースがある点に注意してください。
Amazon DynamoDB(VPCエンドポイント経由)
DynamoDBはパブリックエンドポイントを持ちますが、VPCエンドポイント(Gateway型)をVPCに設定することでインターネットを経由せずにアクセスできます。VPCコネクタ有効時はVPCのルートテーブルを通じてDynamoDB VPCエンドポイントへ到達します。
Amazon OpenSearch Service(旧Elasticsearch)
VPCのプライベートサブネットにデプロイしたOpenSearchドメインへの接続も同様にVPCコネクタ経由で行います。
4-5. プライベートサービス — インバウンドアクセスをVPC内に限定
App Runnerのサービスはデフォルトでインターネット公開です。社内ツール・管理画面・API等でVPC内からのみアクセスを許可したい場合はプライベートサービス(インバウンドVPCエンドポイント)を使用します。
仕組みとしては、ユーザーVPCにInterface型VPCエンドポイント(com.amazonaws.ap-northeast-1.apprunner.requests)を作成し、App RunnerサービスのアクセスタイプをPrivateに設定します。これにより、外部(インターネット)からのアクセスは拒否され、VPC内のリソース(EC2・Lambda・他のApp Runnerサービスなど)からのみアクセスできるようになります。
[社内EC2 / Lambda]
↓
[Interface VPCエンドポイント]
↓
[App Runnerプライベートサービス]
注意点: プライベートサービスはパブリックURLが発行されますが、インターネットからのアクセスは403で拒否されます。VPCエンドポイント経由でのみ正常応答します。カスタムドメインのプライベートサービスへの設定も可能です。
4-6. カスタムドメイン設定とTLS自動管理
App Runnerが自動発行するデフォルトURLは{id}.{region}.awsapprunner.com形式です。本番環境では独自ドメイン(例: api.example.com)を使用するためのカスタムドメイン機能を提供しています。
設定手順
- コンソールまたはCLIでカスタムドメインを追加
- App RunnerがDNSバリデーション用のCNAMEレコードを提示
- Route 53または利用中のDNSプロバイダーにCNAMEを登録
- ドメイン検証完了後、TLS証明書(ACM)が自動発行・自動更新
aws apprunner associate-custom-domain \
--service-arn arn:aws:apprunner:ap-northeast-1:ACCOUNT:service/... \
--domain-name api.example.com \
--enable-www-subdomain false
TLS管理の特徴
TLS証明書はAWS Certificate Manager(ACM)により自動管理されます。証明書の発行・更新・ローテーションはApp Runnerが完全に自動化します。有効期限切れによる障害リスクはありません。HTTP → HTTPSリダイレクトも自動で行われ、HTTPリクエストは301でHTTPSへ誘導されます。
App RunnerはTLS 1.2以上を要求し、古いTLSバージョンの接続は拒否されます。カスタム証明書の持ち込みは現時点では対応しておらず、ACMマネージド証明書が強制されます。
サブドメインの追加
1つのApp Runnerサービスに複数のカスタムドメインを関連付けることができます(例: api.example.com と www.api.example.com)。enable-www-subdomainオプションをtrueにするとwwwサブドメインも自動追加されます。
4-7. WAF連携
App RunnerサービスにはネイティブでAWS WAFを統合できます。WAFウェブACLをApp Runnerサービスに関連付けることで、SQLインジェクション・XSS・レートリミット・IP制限などのルールをアプリケーションコードの変更なしに適用できます。
aws apprunner associate-web-acl \
--service-arn arn:aws:apprunner:ap-northeast-1:ACCOUNT:service/... \
--web-acl-arn arn:aws:wafv2:ap-northeast-1:ACCOUNT:regional/webacl/...
WAFのロギングはKinesis Data Firehose経由でS3に保存でき、CloudWatchメトリクスでブロック数を監視できます。マネージドルールグループ(AWSマネージドルール: Core Rule Set等)と独自カスタムルールを組み合わせた設計が本番での標準構成です。
- VPCコネクタ — プライベートVPCへのアウトバウンド(RDS/ElastiCache等)。AWS Hyperplaneベース・初回2〜5分の起動レイテンシ
- プライベートサービス — VPCエンドポイント経由でVPC内からのみアクセス可能(インバウンド制限)
- カスタムドメイン — 独自ドメイン+自動TLS証明書。WAF連携も可能
- VPC/サブネット/SGの基本構築は既存ネットワーク記事を参照(本節はVPCコネクタ設計に集中)
5. CI/CD・運用

5-1. 自動デプロイの2方式と設定
App Runnerはソースコードデプロイとコンテナイメージデプロイの2方式それぞれに自動デプロイ機能を提供します。デプロイ方式によって自動トリガーの設定方法と動作が異なるため、方式の選択時に合わせて確認しましょう。
ソースコードデプロイの自動トリガー(GitHubコミット連携)
ソースコードデプロイを選択した場合、GitHubリポジトリの指定ブランチへのコミット(プッシュ)が自動デプロイのトリガーになります。App RunnerはGitHub連携に「App Runner GitHub Connection」を使用し、OAuthベースで認証します。AWSマネジメントコンソールで接続設定後、リポジトリ・ブランチ・apprunner.yamlの場所を指定すると、以降はそのブランチへのプッシュを検知して自動的にビルド→デプロイを実行します。
自動デプロイの有効/無効は「デプロイトリガー」設定で切り替えられます。自動に設定するとプッシュのたびにデプロイが走り、手動に設定するとトリガーが発生してもデプロイせず、コンソールやAPIから明示的に実行した場合のみデプロイします。本番環境では意図しないデプロイを防ぐため、ステージング環境を自動・本番環境を手動にするケースが多いです。
apprunner.yamlの記述例です。
version: 1.0
runtime: python311
build:
commands:
build:
- pip install -r requirements.txt
run:
command: uvicorn app.main:app --host 0.0.0.0 --port 8080
network:
port: 8080
env: APP_PORT
env:
- name: ENVIRONMENT
value: production
ビルドコマンドにはテスト実行を含めることもできます。テストが失敗するとビルドフェーズ自体が失敗扱いとなり、デプロイは実施されません。
コンテナイメージデプロイの自動トリガー(ECRプッシュ連携)
コンテナイメージデプロイを選択した場合、Amazon ECRの指定リポジトリへの新しいイメージプッシュが自動デプロイのトリガーになります。App Runnerはリポジトリを監視し、最新のイメージ更新を検知してデプロイを開始します。
ECRへのプッシュを検知して自動デプロイするため、CI/CDパイプライン(CodePipeline・GitHub Actions等)でイメージをビルドしてECRにプッシュするだけで、App Runnerのデプロイまで自動完結します。ソースコードデプロイとの最大の違いは「ビルドフェーズをApp Runnerが持つか、外部のCIが持つか」の点です。イメージデプロイではビルドの制御を自分たちで行えるため、マルチステージビルドや高度なセキュリティスキャンを挟みたい場合に有利です。
GitHub ActionsでECRへプッシュするワークフロー例です。
name: Build and Push to ECR
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: ap-northeast-1
- name: Login to ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
run: |
docker build -t $ECR_REGISTRY/my-app:latest .
docker push $ECR_REGISTRY/my-app:latest
このパイプライン実行後、App RunnerがECRのイメージ更新を検知して自動デプロイを開始します。GitHub Actionsのワークフローとしてはここで完結しており、App Runner側で後続のデプロイ・ヘルスチェック・ロールバックが自動処理されます。
5-2. ヘルスチェック設定
デプロイ中・デプロイ後のインスタンス正常性確認にはヘルスチェックを設定します。ヘルスチェックが失敗し続けると、App Runnerはデプロイを中断して自動的に前のリビジョンへロールバックします。
App RunnerのヘルスチェックにはHTTPとTCPの2プロトコルがあります。
| 設定項目 | 説明 | 推奨値 |
|---|---|---|
| プロトコル | HTTP または TCP | アプリがHTTPを返せるなら HTTP を選択 |
| パス | HTTPヘルスチェックのリクエスト先パス | /health や /ping |
| 間隔(秒) | チェック実行間隔 | 10〜20秒 |
| タイムアウト(秒) | レスポンス待機上限 | 5〜10秒 |
| 正常しきい値 | 正常判定に必要な連続成功回数 | 1〜3回 |
| 異常しきい値 | 異常判定に必要な連続失敗回数 | 3〜5回 |
HTTPヘルスチェックでは指定パスへGETリクエストを送り、HTTP 2xxが返ればOKとみなします。アプリケーションが起動完了した段階で2xxを返す/healthエンドポイントを実装しておくことで、起動途中のインスタンスへのトラフィック流入を防げます。
TCPヘルスチェックはポートへの接続確立のみを確認するため、HTTPエンドポイントが用意できないアプリでも使用できますが、アプリレベルの正常性は確認できません。可能な限りHTTPを選択しましょう。
5-3. デプロイ失敗時のロールバック
App Runnerのデプロイはローリング方式で行われ、新しいリビジョンのインスタンスが正常にヘルスチェックをパスしてから、旧リビジョンのインスタンスがシャットダウンされます。
自動ロールバックの動作: デプロイ中に新しいインスタンスのヘルスチェックが異常しきい値を超えて失敗すると、App Runnerはデプロイを中断し自動的に前のリビジョンへロールバックします。この間もサービスは旧リビジョンで継続稼働しており、エンドユーザーへの影響を最小限に抑えられます。
手動ロールバック: コンソールの「デプロイ」タブから過去のリビジョン一覧を参照し、任意のリビジョンへワンクリックでデプロイできます。CLIからも以下の操作で実施できます。
# 前のイメージタグを指定してサービスを更新(コンテナイメージデプロイの場合)
aws apprunner update-service \
--service-arn arn:aws:apprunner:ap-northeast-1:123456789012:service/my-service/xxxxxxxx \
--source-configuration \
'{"ImageRepository":{"ImageIdentifier":"123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:stable-tag","ImageRepositoryType":"ECR"}}'
自動ロールバックを有効に機能させるためのポイントをまとめます。
- ヘルスチェックを必ず設定する: 未設定の場合はインスタンス起動完了をもって成功とみなし、アプリレベルのエラーを検知できません。
- 起動時間を考慮した間隔設定: アプリの初期化に時間がかかる場合、最初のヘルスチェック到達タイミングを考慮して間隔や正常しきい値を調整します。
- 依存サービスへの接続確認をヘルスチェックへ含める: RDS/ElastiCacheへの接続が成立した後でヘルスチェックをOKとする実装にすると、設定ミスによる本番流入を防げます。
5-4. CloudWatch Logsによるログ管理
App Runnerはアプリケーションログとシステムログを自動的にCloudWatch Logsへ転送します。別途設定不要で、サービス作成直後から利用できます。
アプリケーションログ: アプリがstdout/stderrへ出力した内容がリアルタイムで転送されます。ロググループ名は/aws/apprunner/{service-name}/{service-id}/applicationの形式です。構造化ログ(JSON形式)で出力するとCloudWatch Logs Insightsのクエリで効率よく分析できます。
fields @timestamp, level, message, traceId
| filter level = "ERROR"
| sort @timestamp desc
| limit 50
システムログ: App Runnerインフラ層のログ(デプロイイベント・インスタンス起動・ヘルスチェック結果)が/aws/apprunner/{service-name}/{service-id}/systemに記録されます。デプロイ失敗の原因調査やヘルスチェック失敗の詳細確認に使用します。
ログの保持期間はCloudWatch Logsのロググループ設定で変更できます。デフォルトは無期限のため、コスト管理のため30〜90日程度に設定することを推奨します。
5-5. CloudWatch Metricsによる監視
App RunnerサービスのメトリクスはCloudWatch Metricsに自動収集されます。主要なApp Runnerメトリクスは以下のとおりです。
| メトリクス名 | 説明 |
|---|---|
RequestCount | 受信リクエスト総数 |
RequestLatency | リクエストのレイテンシ(p50/p90/p99) |
2xxStatusResponses | HTTP 2xxレスポンス数 |
4xxStatusResponses | HTTP 4xxレスポンス数(クライアントエラー) |
5xxStatusResponses | HTTP 5xxレスポンス数(サーバーエラー) |
ActiveInstances | 処理中(アクティブ)インスタンス数 |
ConcurrentRequests | 現在の同時リクエスト数 |
CPUUtilization | CPU使用率 |
MemoryUtilization | メモリ使用率 |
5xxエラー率のCloudWatchアラーム設定例です。
aws cloudwatch put-metric-alarm \
--alarm-name "AppRunner-5xx-HighRate" \
--metric-name "5xxStatusResponses" \
--namespace "AWS/AppRunner" \
--dimensions Name=ServiceName,Value=my-service \
--statistic Sum \
--period 60 \
--threshold 10 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 1 \
--alarm-actions arn:aws:sns:ap-northeast-1:123456789012:my-alert-topic
CloudWatchダッシュボードでリクエスト数・レイテンシ・エラー率・インスタンス数を一覧表示しておくと、トラフィックの増減とスケール動作の相関を視覚的に確認できます。ConcurrentRequestsとActiveInstancesを並べて表示すると、スケールアウトの動作タイミングを把握しやすくなります。
5-6. AWS X-Ray・CloudWatch ServiceLensによるトレース
App RunnerはAWS X-Rayとの統合をサービス設定で有効化できます。有効にするとApp RunnerがX-Rayデーモンをサイドカーとして起動し、アプリが生成したトレースデータをX-Rayへ送信します。
X-Ray有効化の設定はマネジメントコンソールでサービスの「設定」→「Observability」セクションから「AWS X-Rayのトレース」を有効化します。有効化後、アプリコードにX-Ray SDKを組み込むことで、受信リクエストから下流のAWSサービス(RDS・DynamoDB・S3・SNSなど)への呼び出しまでのエンドツーエンドトレースを取得できます。
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware
xray_recorder.configure(service='my-app-runner-service')
XRayMiddleware(app, xray_recorder)
CloudWatch ServiceLens: X-Rayのトレースデータ・CloudWatchメトリクス・CloudWatch Logsを統合したビューです。サービスマップでApp Runnerサービスから依存先(RDS・DynamoDB等)への呼び出し経路・レイテンシ・エラー率を視覚的に確認でき、障害発生時のボトルネック特定を迅速化します。
X-Rayサービスマップ上でApp Runnerノードをクリックすると、そのサービスのp50/p90/p99レイテンシとエラー率が表示されます。さらにドリルダウンしてトレース一覧・セグメント詳細(どのAWS API呼び出しに何ミリ秒かかったか)まで確認できます。RDSへのクエリが遅い場合、X-RayのセグメントにSubsegment: RDSとして記録されるため、SQLレベルのボトルネックを素早く特定できます。
- 自動デプロイ — ソースpush/ECRイメージ更新を検知して自動デプロイ(手動も選択可)
- ヘルスチェック(HTTP/TCP)+デプロイ失敗時の自動ロールバック
- 監視 — CloudWatchメトリクス(リクエスト/レイテンシ/5xx/CPU・メモリ)・アプリ/システムログ・X-Rayトレース
- CodePipeline/GitHub Actionsの基本は既存CI/CD記事を参照(本節はApp Runner固有の運用に集中)
6. セキュリティ・コスト
IAMロールの2種類と役割の明確化
App Runnerでは2種類のIAMロールを使い分けることが重要です。混同すると権限エラーが発生し、デプロイ失敗や本番障害の原因となります。
①インスタンスロール(アプリケーションのAWSアクセス用)
インスタンスロールは、App Runnerサービス上で動くアプリケーションコードがAWSサービスへアクセスする際に使用するIAMロールです。アプリケーションがS3にファイルを読み書きする、DynamoDBを参照する、SQSキューにメッセージを送る、Secrets Managerからシークレットを取得する——こうした操作に必要な権限をインスタンスロールに付与します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-app-bucket/*"
},
{
"Effect": "Allow",
"Action": ["secretsmanager:GetSecretValue"],
"Resource": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:my-app/*"
}
]
}
インスタンスロールはApp Runnerサービスの「セキュリティ」設定で指定します。EC2のインスタンスプロファイルやLambdaの実行ロールと同様の概念です。
②アクセスロール(ECRプライベートイメージ取得用)
アクセスロールは、コンテナイメージデプロイ時にApp Runner自体がECRプライベートリポジトリからイメージを取得するために使用するIAMロールです。アプリケーションコードとは別に、App RunnerサービスがECRにアクセスするための権限が必要となります。
必要なポリシーは AWSAppRunnerServicePolicyForECRAccess マネージドポリシーが提供しています。ECRへのアクセス権限が正しく設定されていない場合、デプロイ時に「Unable to pull the image from ECR」エラーが発生します。ソースコードデプロイ(ECRを使わない場合)、アクセスロールは不要です。
この2つのロールを混同するケースが多く、「インスタンスロールにECR権限を付与してもデプロイができない」というトラブルが頻発します。インスタンスロールはアプリコードが使うもの、アクセスロールはApp Runnerサービス自体がECRからイメージを取得するためのものと覚えておきましょう。
Secrets ManagerとSSM Parameter Storeによるシークレット管理
App Runnerでは、データベースのパスワードやAPIキーなどの機密情報を環境変数として直接指定することも技術的には可能ですが、セキュリティ上のリスクがあります。App Runnerのコンソール画面や設定ファイルに機密情報が平文で残ることを避けるため、AWS Secrets ManagerまたはAWS Systems Manager(SSM)Parameter Storeと連携した「シークレット参照」を使用します。
サービス設定の環境変数セクションで、値の代わりにシークレットのARNを指定することで、App Runnerがデプロイとサービスのスタートアップ時にシークレットの値を解決し、環境変数としてアプリケーションに渡します。アプリケーション側は通常の環境変数として参照するだけでよく、Secrets ManagerのAPIを直接呼び出す必要はありません。
運用上の注意点
- シークレットを参照するインスタンスロールに
secretsmanager:GetSecretValueまたはssm:GetParameter権限を付与してください - シークレットのARNはリージョンとアカウントIDを含む完全なARNを指定します
- シークレットをローテーションする場合、App Runnerサービスを再デプロイまたは再起動しないと最新値が反映されません
SSM Parameter Store(SecureString)も同様の方式で参照できます。Secret ManagerはシークレットのローテーションやバージョニングをAWSが管理するため、DBパスワードなど定期ローテーションが必要な機密情報に向いています。SSM Parameter Storeは運用コストを抑えたい設定値・APIキーの管理に適しています。
ネットワーク分離とセキュリティの設計
VPCコネクタを使用することで、App RunnerサービスからプライベートVPC内のリソース(RDS・ElastiCache・内部マイクロサービス等)へのアウトバウンド接続が可能になります(§4で詳述)。これにより、データベース接続などをインターネット経由にする必要がなくなります。
セキュリティグループでApp Runnerからのアクセスを制御でき、RDSの場合は「App Runnerが使用するセキュリティグループからの特定ポートのみ許可」といった最小権限ネットワーク設計が実現できます。
プライベートサービス(インバウンド制限)を活用することで、社内ツール・管理画面・バックエンドAPIをVPC内からのみアクセス可能にする構成も実現できます。
コスト構造:3要素を実数値で理解する
App Runnerのコストは以下の3要素で構成されます。
①ビルドフィー(ソースコードデプロイのみ)
ソースコードデプロイ方式を選択した場合、App Runnerがリポジトリからコードを取得してビルドを実行する時間に対して課金されます。
- 単価(東京リージョン目安): vCPU時間あたり約$0.005/分、メモリGBあたり約$0.0005/分(料金は変動するため、最新のAWSドキュメントを確認してください)
- ビルドが速ければ速いほどビルドフィーは小さくなります
- コンテナイメージデプロイではビルドをApp Runner外(GitHub Actionsなど)で行うため、ビルドフィーは発生しません
②プロビジョンドインスタンス費用(アイドル時のメモリ課金)
アイドル状態のインスタンス(プロビジョンドインスタンス)はメモリの確保を維持するため、アイドル中でもメモリGB課金が発生します。
- 単価(例): 1GBメモリのプロビジョンドインスタンスで約$0.009/時間(東京リージョン目安)
- 最小インスタンス数(Min Size)が1以上の場合、常に最低1台のプロビジョンドインスタンスが維持されます
- 月あたりの試算:最小1インスタンス、1GBメモリの場合、$0.009 × 24時間 × 30日 ≈ $6.5/月
この費用は常時発生する固定的なコストです。最小インスタンス数を0にすることは現在できないため、常にこの費用は発生します。
③アクティブインスタンス費用(リクエスト処理中のvCPU+メモリ課金)
実際にリクエストを処理しているアクティブ状態のインスタンスには、vCPUとメモリの両方に課金されます。
- 単価(例): 1 vCPU・2GBメモリの構成で、アクティブ時間1時間あたり約$0.064/時間(東京リージョン目安)
- リクエスト処理中の秒単位で課金されるため、トラフィックが少ない時間帯はコストが低くなります
- スケールアウトで追加されたインスタンスはそれぞれアクティブ課金の対象となります
VPCコネクタ自体の料金
VPCコネクタ自体の利用は無料です。ただし、VPCコネクタを通じたデータ転送(NAT Gatewayを経由する場合)やVPCエンドポイントの利用は別途課金されます。
月次コスト試算例
| 構成 | 想定トラフィック | 月次コスト目安 |
|---|---|---|
| 1 vCPU・2GB、最小1台 | 低トラフィック(開発/ステージング) | $10〜$20/月 |
| 1 vCPU・2GB、最小1台 | 中トラフィック(本番小規模) | $20〜$50/月 |
| 2 vCPU・4GB、最小1台 | 中〜高トラフィック(本番中規模) | $50〜$150/月 |
実際のコストはトラフィックパターンと設定に大きく依存します。AWSコスト見積もりツール(AWS Pricing Calculator)で事前に試算することを推奨します。
コスト最適化の実践的アプローチ
最小インスタンス数の適正化
最小インスタンス数(Min Size)の設定は最もコストに直結するパラメーターです。
- Min Size = 1(推奨): プロビジョンドインスタンスが常に1台維持され、コールドスタートなしで応答できます。月$6〜$15程度のベースコストが発生します
- Min Size > 1: 高負荷常時対応や冗長性が必要な本番環境向け。その分プロビジョンド費用が増加します
「とりあえずインスタンス数を多めに」という設定はアイドル時のコスト増大の主因です。トラフィックパターンを分析し、最小限の冗長性で設計することが重要です。
最大インスタンス数によるコスト上限の設定
App RunnerはMax Sizeを設定することでスケールアウトの上限を制限できます。コストの上限を制御するために必ず設定することを推奨します。Max Sizeを設定しない(または大きすぎる値を設定する)と、予期しないトラフィックスパイクで多数のインスタンスが起動し、コスト急増のリスクがあります。
vCPU・メモリの適切な選択
App Runnerで選択できるvCPU/メモリの組み合わせは、0.25 vCPU・0.5GB から 4 vCPU・12GB まで複数あります。実際の負荷に合わせた適切なサイズ選択がコスト最適化の鍵です。CloudWatchのCPU/メモリ使用率メトリクスを監視し、過剰スペックな設定を見直します。
ECS Fargate常時起動との比較
App Runnerとの比較対象としてよく挙げられるのがECS Fargateです。
App Runnerが有利なケース
- トラフィックが間欠的・スパイク型(アイドル時にプロビジョンドインスタンスのみ課金)
- インフラ管理コストを削減したい(App RunnerはALBやオートスケール設定が不要)
- 小〜中規模の本番サービスを少ない運用リソースで維持したい
ECS Fargateが有利なケース
- 24時間高負荷が続く常時起動サービス(ECS Fargateはタスク起動中も常時課金されますが、細かなリソース指定が可能)
- 複数のコンテナを1タスクで動かすサイドカーパターン
- 複数のターゲットグループや詳細なロードバランサー設定が必要な場合
選定に迷った場合は「まずApp Runnerで始め、要件が複雑化したらECS/EKSへ移行する」成長パスが現実的です。App RunnerはOCI準拠のコンテナイメージを使用するため、ECSへの移行コストは比較的低いです。
- セキュリティ=インスタンスロール(アプリのAWSアクセス)とアクセスロール(ECR取得)を区別。VPCコネクタで分離
- ★コスト=ビルドフィー+プロビジョンド(アイドル時メモリGB課金)+アクティブ(処理中vCPU+メモリ課金)
- アイドルでもプロビジョンド課金が発生。最小インスタンス数の過大設定がコスト増の主因
- 最大インスタンス数でコスト上限制御。常時高負荷ならECS Fargateとのコスト比較も検討
7. 実戦統合パターン — ECS/EKS/Lambdaとの使い分け

AWS上でコンテナを実行する選択肢は多岐にわたります。App Runner・ECS・EKS・Lambda・Fargateはそれぞれ異なる設計思想と適用領域を持ちます。§7では実際の要件に即した選定基準と、それぞれのサービスをどのように組み合わせて使うかを解説します。
選定フローチャートの読み方
fig06のフローチャートは以下の問いを軸に構成されています:
- 実行単位は何か? → 関数(短時間処理・イベント駆動)であればLambda、コンテナ(長時間・HTTP)であれば次へ
- Kubernetesが必要か? → Kubernetes標準API・エコシステム(Helm、Operators、CRD)が必要であればEKS
- インフラ細部の制御が必要か? → サイドカーコンテナ・カスタムネットワーキング・複雑なサービスメッシュが必要であればECS
- それ以外 → App Runner(最速・最小運用でURL公開)
このフローは「必要な制御の細かさ」が選定基準の核心です。App Runnerは「最小の運用負荷でコンテナをHTTPで公開する」ことに最適化されており、それ以外の要件が増えるほどECS・EKS・Lambdaに寄っていきます。
App Runnerが向くケース・向かないケース
App Runnerの適用範囲を明確にしておくことが、後の移行判断を楽にします。
App Runnerが向くケース
- 小〜中規模のWeb/API: REST API・GraphQL API・Webアプリの迅速なデプロイ
- インフラ専任チームがいない環境: スタートアップ・社内ツール・小規模プロダクトでインフラ運用リソースが限られる場合
- 高速立ち上げ: プロトタイプ・MVPの開発や、最初のデプロイを最速で完了させたい場合
- シンプルなスケール要件: 同時実行数〜数百、インスタンス数〜数十程度が想定される場合
App Runnerが向かないケース
- 複雑なネットワーク制御: ALBの細かなルーティング・サービスメッシュ・サイドカーが必要な場合
- バッチ・長時間処理: コンテナを起動してジョブを実行し終了するパターン(ECS Taskが適切)
- きめ細かいスケール制御: CPU/メモリ以外のカスタムメトリクスによるスケール・予測スケーリング
- 大規模マイクロサービス: 数十〜数百のサービスを統一した方法で管理・運用
- Kubernetes標準が必要: Helm・Operators・CRDを活用したい場合
App Runner vs ECS Fargate 詳細比較
App RunnerとECS Fargateは、どちらもEC2インスタンスのクラスター管理が不要な点で共通しています。しかし設計思想と制御レベルが大きく異なります。
| 項目 | App Runner | ECS Fargate |
|---|---|---|
| クラスター管理 | 不要 | 不要(ECSクラスターはあり) |
| タスク定義 | 不要(サービス設定のみ) | 必要 |
| ロードバランサー | 自動付与(カスタム不可) | ALB/NLB自由設定 |
| サイドカー | 非対応 | 対応 |
| バッチジョブ | 非対応 | ECS Taskとして実行可能 |
| スケーリングトリガー | 同時実行数(自動) | CPU/メモリ/カスタムメトリクス |
| VPC | オプション(VPCコネクタ) | 必須(VPC内にデプロイ) |
| 起動速度 | 高速(プロビジョンド有り) | 数十秒〜数分(Fargate起動時間) |
| 設定の複雑さ | 低 | 中〜高 |
ECS Fargateが向く状況: サイドカーパターン(DatadogエージェントやEnvoyプロキシを同一タスク内に共存)、複雑なタスク定義(複数コンテナ・ボリューム共有)、ALBの柔軟な設定(パスベースルーティング・スティッキーセッション)、バッチジョブ、大規模・高スループットでの細かなスケーリングポリシー制御が必要な場合。
App Runner vs Lambda 詳細比較
LambdaはApp Runnerと比較して「イベント駆動の関数実行」に特化しています。
Lambdaが向く状況
- 非同期処理・イベント駆動: S3アップロード・SNSメッセージ・SQSキュー・EventBridgeイベントに反応する処理
- 短時間処理: 最大実行時間は15分(Lambda制限)以内で完了する処理
- まれに大量実行するバースト型ワーク: 普段はリクエストなしで突発的に大量実行するパターン
- マイクロサービスの最小単位: 独立した変換・検証・通知などの単機能処理
組み合わせパターン(App Runner + Lambda)
実際のシステムでは両者を組み合わせることが最も効果的です:
- フロントエンドAPI: App Runner(常時応答・コンテナ運用)
- バックグラウンド処理: Lambda(非同期・イベント駆動)
- 通知・変換パイプライン: Lambda(SQS→Lambda→DynamoDB)
- 画像サムネイル生成: S3→Lambda(App RunnerのAPIはURLを返すのみ)
App Runner vs EKS 詳細比較
EKSはKubernetesマネージドサービスであり、App Runnerとは最も設計目標が異なります。
EKSが向く状況
- Kubernetes標準エコシステム: Helm Charts・Operators・Istio・ArgoCD・Prometheus/Grafanaスタックを活用したい場合
- マルチクラウド・ポータビリティ: KubernetesマニフェストをオンプレミスやGKE・AKSと共通化
- 高度なスケーリング: KEDA(Kubernetes Event-driven Autoscaling)・カスタムメトリクス
- 大規模マイクロサービス: 数十〜数百のサービスを統一した方法で管理・運用
- 複雑なデプロイ戦略: BlueGreen・Canary・Progressive Deliveryの実装
App RunnerはKubernetes学習コストなしで、即座に本番デプロイが可能です。チームがKubernetesエコシステムに習熟しておらず、サービス数も少ない場合はApp Runnerが適切な選択です。
マルチサービス構成でのApp Runner活用パターン
パターン1: マイクロサービス分割
複数の独立したAPIサービスをそれぞれApp Runnerサービスとしてデプロイします。各サービスは独立したオートスケール設定を持ち、ソースリポジトリへのpushで個別にデプロイされます。
クライアント
↓
Amazon Route 53(APIサブドメイン分散)
├── auth.api.example.com → App Runner: auth-service
├── product.api.example.com → App Runner: product-service
└── order.api.example.com→ App Runner: order-service
パターン2: App Runner + RDS + ElastiCache(VPCコネクタ経由)
標準的なWebアプリのバックエンド構成です。VPCコネクタを使ってプライベートサブネットのデータベース・キャッシュへ安全に接続します。
クライアント
↓
App Runner サービス
↓(VPCコネクタ経由)
Private Subnet
├── RDS Aurora(DB)
├── ElastiCache Redis(セッション・キャッシュ)
└── OpenSearch Service(全文検索)
パターン3: App Runner + SQS + Lambda(非同期ワーカー分離)
同期的なAPIリクエストを処理するApp Runnerと、非同期処理を行うLambdaを組み合わせたパターンです。
クライアント → App Runner API
↓(SQSへメッセージ投入)
SQS Queue
↓(ポーリング)
Lambda Worker
↓
DynamoDB / S3 / 外部API
APIの応答性を維持しながら重い処理をバックグラウンドに分離できます。
パターン4: CDN + App Runner(静的・動的分離)
CloudFrontをフロントに置き、静的コンテンツはS3、動的処理はApp Runnerに振り分けるパターンです。
クライアント
↓
Amazon CloudFront
├── 静的コンテンツ → S3
└── /api/* → App Runner(動的API)
成長パス — App RunnerからECS/EKSへの移行
App Runnerは「素早く始める」ことに優れており、プロダクトが成長するにつれてECSやEKSへの移行を検討するケースもあります。
App Runnerを継続すべき状態
- 同時実行・インスタンス数がMaxSizeの上限内に収まっている
- サイドカーコンテナが不要
- バッチ処理をLambdaで補完できている
- チームがALBの細かな設定を必要としていない
ECSへの移行を検討すべきサイン
- サイドカーコンテナ(DatadogAgent・Envoy)が必要になった
- ALBの複雑なルーティング設定が必要になった
- バッチジョブをコンテナとして同一ECSクラスター上で管理したい
EKSへの移行を検討すべきサイン
- チームがKubernetesに習熟し、HelmやArgoCDを活用したい
- マルチクラウド戦略でKubernetesの統一管理が必要
移行時、コンテナイメージ・Dockerfile自体はそのまま流用できます。App RunnerからECSへの移行では、ECSタスク定義・サービス定義の作成とALBの設定が主な作業となります。
既存コンテナ・サーバーレス・Compute記事との連携全体像
本記事(App Runner本番運用Vol1)は、以下の既存記事シリーズと連携しています。それぞれの記事が扱うサービスの特性を理解した上で、要件に合ったアーキテクチャを構築してください。
| 記事 | サービス | 使い分けの基準 |
|---|---|---|
| コンテナ本番運用 Vol1(ECS/Fargate/ECR) | ECS Fargate | 細かなオーケストレーション・サイドカー・バッチ |
| コンテナ本番運用 Vol3(EKS) | EKS | Kubernetes標準・大規模マイクロサービス |
| サーバーレス本番運用(Lambda/API GW) | Lambda | イベント駆動・短時間関数・非同期処理 |
| Compute本番運用 Vol1(EC2/Auto Scaling) | EC2 | インフラ完全制御・特殊ワークロード |
| 本記事(App Runner本番運用 Vol1) | App Runner | 最速・最小運用のWeb/API公開 |
これらの記事を横断的に参照することで、AWS上のコンテナ・サーバーレス・Computeの全体像を把握し、要件に最適なサービスを選択できるようになります。
- URL公開のWeb/APIを最速・最小運用で → App Runner(本記事)
- 細かなオーケストレーション制御・サイドカー・大規模 → ECS / Kubernetes標準 → EKS
- イベント駆動・短時間関数 → Lambda
- 成長パス — App Runnerで速く始め、要件が複雑化したらECS/EKSへ移行
関数単位の実行はこちら(サーバーレス本番運用 — Lambda/API Gateway/Step Functions)
Kubernetes標準ならこちら(コンテナ本番運用 Vol3 — EKS)
8. つまずきポイント・アンチパターン・まとめ
App Runnerを実際に本番運用すると、フルマネージドゆえの独自の罠に遭遇します。本節では現場でよく報告されるつまずきポイントとアンチパターンを整理し、安定した本番運用に役立てていただきます。
つまずきポイント
1. 同時実行しきい値の誤設定によるスケール過剰・不足
App Runnerのオートスケールは「1インスタンスあたりの同時リクエスト数しきい値」に基づいて動作します。しきい値をデフォルト値(100)のまま使い続けると、実際の負荷パターンに合わず問題が起きます。しきい値が高すぎる場合はスケールアウトが遅れてレイテンシが悪化し、低すぎる場合はインスタンス数が増えすぎてコストが膨らみます。
CloudWatchのConcurrentRequestsメトリクスとActiveInstancesメトリクスを組み合わせて参照し、1インスタンスあたりの実際の同時リクエスト数を計測してしきい値を調整してください。レイテンシが重要なAPIでは低めに(20〜30程度)、スループット重視の処理では高めに(80〜100程度)設定するのが一般的です。
初期値として同時実行しきい値を25程度に設定し、負荷試験の結果を見ながら段階的に調整するアプローチがトラブルを防ぎやすいです。設定変更はAuto Scaling Configurationの更新のみで即時反映され、サービスの再デプロイは不要です。
2. VPCコネクタの初回起動レイテンシを見落として障害誤認
App RunnerにVPCコネクタをアタッチすると、初回のサービス起動時やコネクタ作成直後に2〜5分の追加レイテンシが発生します。これはAWS HyperplaneでのENIプロビジョニング時間です。デプロイ直後にアクセスしてタイムアウトが続いても、障害ではなくVPCコネクタの初期化中である可能性があります。
監視アラームの起動遅延設定を適切に行うことで誤アラームを防止できます。またプロビジョンドインスタンスを使うことでアイドル後の再起動時のレイテンシを短縮できます。
3. プロビジョンドインスタンスのアイドル課金を見落とし
App Runnerはアイドル時にインスタンスを完全停止せず、プロビジョンド状態(CPUスロットル)に縮退します。このプロビジョンドインスタンスにはメモリGB単位の課金が発生します。「アクティブリクエストがないのになぜコストが発生するのか」と疑問を持つケースが多いです。
最小インスタンス数を1以上に設定している場合、そのインスタンス分のプロビジョンドコストが常時発生します。コスト最適化のために最小インスタンス数を0にするか、コールドスタートとプロビジョンドコストのトレードオフを意識した設計が必要です。
4. ソースコードデプロイのビルドフィーを予算計画に含めていない
ソースコードデプロイでは、デプロイのたびにビルドフィーが発生します。頻繁にデプロイする開発・ステージング環境では、ビルドフィーが積み重なり想定外のコストになるケースがあります。月次のAWS Cost ExplorerでAWS App Runnerのコスト内訳を確認し、ビルドフィーの占める割合を把握してください。
本番環境では、ビルドはGitHub ActionsやCodeBuildで実行してECRにpushし、App RunnerはECRからのイメージデプロイに切り替えることで、ビルドフィーを完全に排除できます。
5. インスタンスロールとアクセスロールを混同して権限エラー
App Runnerには2種類のIAMロールが存在します。アクセスロールはApp RunnerがECRからイメージをPullするためのロール、インスタンスロールはアプリ自体がAWSサービス(DynamoDB/S3/SQS等)を呼び出すためのロールです。
アクセスロールへDynamoDBの権限を付けてもアプリには届きません。逆にインスタンスロールへECRのPull権限を付けてもデプロイは成功しません。この区別を誤ると、実行時にAccess Deniedが出てもどちらを修正すべきか分からず、トラブルシュートに時間がかかります。サービス作成時に「ECRアクセスロール」と「サービスロール(インスタンスロール)」を明確に分けて設定してください。
6. 長時間処理・バッチ処理をApp Runnerで実行しようとする
App Runnerはリクエスト/レスポンス型のWebアプリ・APIに最適化されています。バッチ処理や数十分かかる長時間処理には向いていません。リクエストタイムアウトの制限があり、長時間リクエストは途中で切断される可能性があります。
バッチ処理はSQSとLambdaの組合せ、またはECSタスクで実装し、App RunnerはフロントAPIとして薄く使うアーキテクチャが安定します。「一応動かせるが、タイムアウト設計が複雑になり運用が辛くなる」がApp Runnerでバッチを組む際の典型的な結末です。
7. 最大インスタンス数を未設定(または大きすぎる値に)でコスト暴走
Auto Scaling Configurationで最大インスタンス数を未設定のまま、または非常に大きな値のまま運用すると、急激なトラフィック増加時のインスタンス数が無制限となりコスト暴走につながります。特にDDoSや予期しないスパイク時は、請求ショックへと発展するケースが報告されています。
本番環境では、最大インスタンス数 × インスタンス単価でコスト上限を計算し、ビジネス要件と予算を照らし合わせた上で設定してください。最大数に到達したらアラームで検知し、スケール限界に達したことをオンコールチームが把握できる仕組みを合わせて用意しておきます。
8. ヘルスチェックを省略してロールバックが機能しない
App Runnerのヘルスチェックはデプロイ成功の判定に直結します。ヘルスチェックを設定していないと、アプリが起動しても正しく応答できていない状態でデプロイが「成功」とみなされ、自動ロールバックが働きません。
/healthエンドポイントを実装し、アプリケーションの初期化完了後にのみHTTP 200を返す設計にします。ヘルスチェックパス・タイムアウト・しきい値(不健全になるまでの失敗回数)を明示的に設定することで、デプロイの品質ゲートとして機能します。データベース接続確認を/healthに含めると、設定ミスによる本番流入を事前に防げます。
アンチパターンと正解
本番でよく見られるアンチパターンとその改善策を整理します。
| アンチパターン | 問題 | 正解 |
|---|---|---|
| ソースコードデプロイを本番で常用 | ビルドフィー積算・ランタイムバージョンの柔軟性なし | ECRイメージデプロイ + CI/CDでビルド分離 |
| インスタンスロールとアクセスロールを同一視 | ECR PullやAWSアクセスで権限エラーが頻発 | 2つのロールを明確に分離し最小権限で設定 |
| 最大インスタンス数を未設定 | スパイク時にコスト暴走・請求ショック | 最大インスタンス数を必ず設定してコスト上限を制御 |
| 最小インスタンス数を過大設定 | 24時間プロビジョンドコストが発生し続ける | コールドスタート許容度に合わせて最適化 |
latestタグのみでイメージ管理 | どのバージョンがデプロイされているか追跡不可 | コミットSHAまたはセマンティックバージョンをタグに使用 |
| App Runnerで重いバッチを実行 | タイムアウト・リトライ制御なし・コスト非効率 | バッチはSQS + Lambda / ECSタスクで実装して分離 |
App Runnerコスト構造と見積もりの考え方
App Runnerのコストは以下の3要素で構成されます。見積もり精度を高めるために、各要素を個別に計算してから合算してください。
① ビルドフィー(ソースコードデプロイ時のみ)
ビルド実行時間(分)単位の課金です。ビルド時間が長いほど、デプロイ頻度が高いほど積算されます。本番移行後にコンテナイメージデプロイへ切り替えることでゼロにできます。
② プロビジョンドインスタンスコスト(アイドル時)
インスタンスがリクエスト処理をしていないアイドル時間に、メモリGB・時間単位で課金されます。最小インスタンス数 × メモリサイズ × アイドル時間が費用の目安です。24時間アイドルが続く環境(開発環境等)では、最小インスタンス数を0にするか、コスト上限を意識した設計が重要です。
③ アクティブインスタンスコスト(リクエスト処理中)
vCPU・時間単位とメモリGB・時間単位の合計です。実際のリクエスト処理時間が課金の基準となります。1日のリクエスト数とリクエストあたりの平均処理時間から推算できます。
コスト比較の目安(東京リージョン・1 vCPU/2 GB例)
| 状態 | 単価の目安 | 発生条件 |
|---|---|---|
| プロビジョンド | メモリのみ課金 | アイドル時(常時) |
| アクティブ | vCPU + メモリ課金 | リクエスト処理中 |
| ビルド | ビルド時間課金 | ソースデプロイ時 |
ECS Fargate常時起動と比較すると、リクエスト数が少ない時間帯ではApp Runnerのアイドル縮退が有利です。一方で常時高負荷な状況では、Fargateの方がコスト効率の面で優位になるケースもあります。実際のトラフィックパターンをもとにAWS Pricing Calculatorで比較試算を行ってから採用判断することを推奨します。
本番リリース前のチェックリスト
本番環境へApp Runnerサービスを投入する前に確認すべき項目を整理します。
デプロイ設定
- [ ] コンテナイメージデプロイを使用しているか(ソースコードデプロイから切り替え済みか)
- [ ] イメージタグがコミットSHAまたはバージョン番号になっているか(
latestタグのみでないか) - [ ] ECRアクセスロールとインスタンスロールが正しく分離されているか
- [ ] デプロイトリガーが意図通り(Automatic/Manual)に設定されているか
スケール・リソース設定
- [ ] Auto Scaling Configurationで最大インスタンス数を設定しているか
- [ ] 同時実行しきい値を負荷試験結果に基づいて調整しているか
- [ ] vCPU・メモリ設定が実際のアプリのメモリ消費に対して適切か
ネットワーク・セキュリティ
- [ ] VPCコネクタのステータスがACTIVEであることを確認したか
- [ ] RDS/ElastiCacheのセキュリティグループでVPCコネクタSGからのインバウンドを許可しているか
- [ ] シークレット(DB接続文字列等)がSecrets ManagerまたはSSM経由で参照されているか(平文の環境変数でないか)
ヘルスチェック・監視
- [ ]
/healthエンドポイントが実装され、HTTP 200を返すことを確認したか - [ ] ヘルスチェックパス・タイムアウト・しきい値を明示的に設定したか
- [ ] CloudWatchアラーム(5xxエラー率・レイテンシ)を設定したか
- [ ] CloudWatch Logsのロググループ保持期間を設定したか(デフォルト無期限)
コスト管理
- [ ] 最大インスタンス数からコスト上限を計算し、予算内に収まることを確認したか
- [ ] AWS Budgetsでコストアラームを設定したか
- [ ] 月次でAWS Cost Explorerを確認し、プロビジョンドコストとアクティブコストの割合を把握する習慣があるか
まとめ — App Runner本番運用 Vol1のポイント
本記事では、App Runnerのデプロイ2方式から本番運用に必要な基礎設計までを解説しました。要点を振り返ります。
デプロイ方式の選択
ソースコードデプロイはプロトタイプ・小規模向けで素早く始められます。本番では、ビルドをCI/CDで分離したコンテナイメージデプロイが推奨です。コミットSHAをイメージタグに使い、デプロイ履歴の追跡を明確にします。
オートスケールとコスト設計
同時実行しきい値・最小/最大インスタンス数・vCPU/メモリの組合せ設計が、スループットとコストの両立に直結します。プロビジョンドコストとコールドスタートのトレードオフを意識した設計が肝心です。
VPCコネクタとネットワーク
プライベートVPCリソース(RDS/ElastiCache)へのアクセスはVPCコネクタ経由で実現できます。初回起動レイテンシを考慮した監視設定を合わせて行いましょう。
セキュリティとIAM
インスタンスロールとアクセスロールの役割を明確に区別し、それぞれ最小権限を付与します。シークレットはSecrets ManagerまたはSSMパラメータストアを経由して参照し、環境変数に平文で書かないことが原則です。
使い分けの軸
最小運用でURL公開できるWeb/APIはApp Runner、細かなオーケストレーション制御が必要な大規模構成はECS/EKS、関数単位のイベント駆動処理はLambdaと、サービスの特性に応じて選択してください。本節で整理したつまずきポイントとチェックリストを活用することで、本番投入前のリスクを大幅に低減できます。
本番運用の継続改善
App Runnerサービスをリリースした後も、CloudWatchメトリクスを定期的に確認して同時実行しきい値の最適化を続けることが重要です。トラフィックパターンは季節・キャンペーン・ユーザー数の成長とともに変化します。月次でAWS Cost Explorerを確認し、プロビジョンドコストとアクティブコストのバランスが適切かどうかをレビューする習慣をつけてください。
Vol2では、VPCコネクタとプライベートサービスの詳細構成、カスタムドメイン/WAF連携、CI/CDパイプラインとの組み合わせを深掘りします。App Runner本番運用の全体像を体系的に理解するために、Vol2以降も合わせてご参照ください。
App Runner vs ECS Fargate — 選択基準の整理
App RunnerとECS Fargateはどちらも「クラスター管理不要でコンテナを実行する」手段ですが、抽象度と柔軟性のトレードオフが異なります。本番導入前に以下の判断基準を確認してください。
App Runnerが適するケース
App Runnerはインフラ専任エンジニアがいないチームや、クイックなプロトタイプから本番への移行を優先する状況に最適です。次の条件が重なるほど適合度が上がります。
- HTTPSエンドポイントを持つWebアプリ・APIを最小運用で公開したい
- コンテナ数が少なく、シンプルな1コンテナ構成で完結する
- 同時実行ベースのオートスケールで要件が満たせる
- インフラの詳細設定よりアプリ開発に集中したい
ECS Fargateが適するケース
細かな制御が必要になった場合は、ECS Fargateへの移行を検討してください。
- サイドカーコンテナ(ログエージェント・Envoy等)を同一タスクで動かしたい
- デプロイ戦略(Blue/Green・カナリア)を細かく制御したい
- スケジュールタスク・ワンショットバッチをコンテナで実行したい
- Service Connectによるサービスディスカバリが必要
成長パス
App Runnerでスタートし、要件が複雑化したらECS/EKSへ移行する「ターンキー→制御拡大」の成長パスが現実的な選択肢です。App RunnerのサービスはDockerイメージを使っているため、イメージをそのままECSタスク定義に移植できます。
App Runnerで本番経験を積むと、実際のトラフィックパターン・必要なリソース量・依存サービスの接続構成が明確になります。その実績をもとにECSへの移行設計を行うと、過剰スペックや設計ミスのリスクを最小限に抑えられます。「まず動かす・測る・最適化する」のサイクルをApp Runnerで素早く回し、規模が拡大した段階でECS/EKSへ移行するアプローチは、クラウドネイティブ開発の定石のひとつです。
- App Runnerはソース/イメージからURL公開まで全自動の最簡コンテナ実行サービス(クラスター管理不要)
- 同時実行ベースのオートスケール+アイドル縮退。VPCコネクタでプライベートリソースへ接続
- コストはビルド+プロビジョンド+アクティブの3要素。最小/最大インスタンス数の設計が肝
- 最速・最小運用ならApp Runner、細かな制御はECS/EKS、関数はLambdaと使い分ける