はじめに
Amazon Bedrock AgentCore Runtime に自分の EC2 インスタンス上でエージェントを動かせる新しいコンピュートタイプ「Runtime Instances」が追加されました。
これまで AgentCore Runtime は microVM(サーバーレス)一択で、最大 8 時間しかセッションを維持できませんでした。
長時間動き続けるエージェントや GPU を使いたいエージェントは自前で EC2 を組むしかなかったのですが、今回のアップデートでその管理を AgentCore へ任せられるようになります。
忙しい人のための要約
- AgentCore Runtime に「Instances」というコンピュートタイプが追加され、自分のアカウント内の EC2 でエージェントを動かせるようになった
- 最大 14 日間のセッション維持、GPU インスタンス対応、同一インスタンス上での複数エージェント協調(コラボレーション)が可能
- インスタンスのプロビジョニング・パッチ適用・スケーリングは AgentCore が管理してくれるが、リソースは自分のアカウント/VPC に立つので既存の Savings Plans や オンデマンドキャパシティ予約(ODCR)がそのまま使える
Runtime Instances とは
AgentCore Runtime にはこれまで「microVM」というコンピュートタイプしかありませんでした。リクエストが来るたびに軽量な仮想マシンが立ち上がるサーバーレスな仕組みで、起動が速い一方、1 セッションの寿命は最大 8 時間までという制約があります。
今回追加された「Instances」は、これとは別に選べるもう一つのコンピュートタイプです。Capacity ProviderというリソースでEC2 の OS・インスタンスタイプ・ネットワーク・ストレージを定義しておき、それを Runtime に紐付けると、AgentCore がその EC2 インスタンスを自分のアカウント内にプロビジョニングしてエージェントを実行してくれます。
2 つのコンピュートタイプを比較すると、次のようになります。
| 項目 | microVM | Instances |
|---|---|---|
| 得意な用途 | 短時間で終わる API 駆動のエージェント | 長時間動き続ける・GPU が要る・複数エージェントが協調するワークロード |
| 管理モデル | フルマネージド・サーバーレス | 自分のアカウントの EC2 を AgentCore が管理(パッチ・スケーリング) |
| 最大セッション時間 | 8 時間 | 14 日間 |
| GPU 対応 | 非対応 | 対応(ドライバは AgentCore が用意) |
| 1 インスタンスあたりのエージェント数 | 1:1 | 1:N(複数エージェントが同居してファイル共有可能) |
| 課金 | AgentCore の従量課金 | EC2 実費(Savings Plans/ODCR 適用可)+管理コスト |
何がうれしいのか
- 長時間ジョブが組める: データ変換や継続的な自動化のように、8 時間を超えて動き続ける必要があるエージェントを AgentCore の枠組みの中で扱える
- GPU が使える: 3D レンダリングやシミュレーション、モデル推論のような計算負荷の高いタスクを、GPU ドライバの準備なしにコンテナイメージそのままで実行できる
-
エージェント同士の協調: 同じ Capacity Provider と同じ
runtimeSessionIdを指定すれば、複数の Runtime(=複数エージェント)を同じインスタンス上に載せ、同じファイルシステムを共有させられる - 既存のコスト最適化がそのまま使える: インスタンスは自分のアカウント/VPC に立つので、Savings Plans や ODCR をそのまま適用できる
やってみた
全体のアーキテクチャ
Step0: サンプルエージェントをビルドしてECRにpushする
CloudFormation で参照するコンテナイメージが必要なので、先に AgentCore の標準的な作り方(bedrock_agentcoreSDK + Strands Agents)でサンプルエージェントを用意します。
`
bedrock-agentcore
strands-agents
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from strands import Agent
from strands.models import BedrockModel
app = BedrockAgentCoreApp()
model = BedrockModel(model_id="jp.anthropic.claude-haiku-4-5-20251001-v1:0")
agent = Agent(
model=model,
system_prompt="あなたは親切なアシスタントです。簡潔に日本語で回答してください。",
)
@app.entrypoint
def invoke(payload):
user_input = payload.get("prompt", "")
if not isinstance(user_input, str) or not user_input.strip():
return {"error": "'prompt' must be a non-empty string"}
response = agent(user_input)
return {"result": response.message["content"][0]["text"]}
if __name__ == "__main__":
app.run()
FROM --platform=linux/amd64 python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY agent.py .
EXPOSE 8080
CMD ["python", "agent.py"]
ECRリポジトリを作成し、docker buildx でビルド&push します。
# ECRリポジトリを作成
aws ecr create-repository \
--repository-name bedrock-agentcore-instances-sample \
--region ap-northeast-1
# ECRにログイン
aws ecr get-login-password --region ap-northeast-1 \
| docker login --username AWS --password-stdin \
<AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com
# amd64向けにビルドしてそのままpush
docker buildx create --use
docker buildx build --platform linux/amd64 \
-t <AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/bedrock-agentcore-instances-sample:latest \
--push .
このイメージの URI を、後述するテンプレートの ContainerImageUri パラメータに渡します。
Step1: IAM ロールを CloudFormation で定義する
Instances 方式では、通常の Runtime 実行ロールに加えて 2 つのロールが必要です。
| ロール | 説明 |
|---|---|
| Instance profile role | EC2 インスタンスにアタッチされ、AgentCore がシステムログを収集するために使う(エージェントコード自体の権限には関与しない) |
| Infrastructure role(Capacity Provider Operator Role) | AgentCore がこのロールを引き受けて、アカウント内の EC2 インスタンスをプロビジョニング・タグ付け・ネットワーク設定する |
Infrastructure role には、AWS 管理ポリシー BedrockAgentCoreRuntimeInstancesOperatorRolePolicy をそのままアタッチするのが確実です。EC2 の RunInstances/TerminateInstances/ ボリューム操作などが AgentCore 管理下のリソースに限定される形で定義されています。
Step2: Capacity Provider を CloudFormation で定義する
EC2 の OS・許可するインスタンスタイプ・VPC/サブネット・EBS ボリュームを AWS::BedrockAgentCore::CapacityProvider で定義します。ドキュメント上は GPU 使用時に family が限定される制約しか明記されていませんが、実際にt3.smallで試したところ「東京リージョンでは未対応」というエラーになりました。T 系(バースト可能)インスタンスはサポート対象外のようです。コスト最小化はいったん諦め、公式サンプルにも登場する m5.large(汎用インスタンスの最小サイズ)を使い、エージェントの作業領域として 8 GiB の EBS ボリュームを 1 本アタッチしました。
Step3: Agent Runtime を CloudFormation で定義する
AWS::BedrockAgentCore::Runtime で、CapacityProviderConfiguration に Step2 で作った Capacity Provider の ARN を渡します。Capacity Provider 側で定義した EBS ボリューム(scratch)をエージェントのファイルシステムにマウントする場合は、FilesystemConfigurations に CapacityProviderVolume を追加します。
AWS::BedrockAgentCore::CapacityProvider は ComputeConfiguration が Update requires: Replacement なので、インスタンスタイプやネットワーク構成を後から変えたい場合は作り直しになる点にも注意しましょう。
完全な CloudFormation テンプレート
以上の 3 ステップで登場したリソース(IAM ロール 3 つ・Capacity Provider・Agent Runtime)を 1 本のテンプレートにまとめました。Parameters で VPC のサブネット・セキュリティグループ・エージェントのコンテナイメージURI を渡せば、そのままコピペしてデプロイできます。
template.yaml(クリックで展開)
AWSTemplateFormatVersion: "2010-09-09"
Description: >
Amazon Bedrock AgentCore Runtime Instances (Capacity Provider方式) のハンズオン用スタック。
IAMロール・Capacity Provider・Agent Runtimeを一括で作成します。
Parameters:
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: Capacity Providerが起動するEC2インスタンスを配置するサブネット
SecurityGroupId:
Type: AWS::EC2::SecurityGroup::Id
Description: EC2インスタンスに割り当てるセキュリティグループ
ContainerImageUri:
Type: String
Description: >
エージェントのコンテナイメージURI
(例: 111122223333.dkr.ecr.ap-northeast-1.amazonaws.com/my-agent:latest)
Resources:
# --- Runtimeの実行ロール(通常のAgentCore Runtimeと同じ) ---
AgentRuntimeExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: agentcore-instances-runtime-role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: bedrock-agentcore.amazonaws.com
Action: sts:AssumeRole
Condition:
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
ArnLike:
aws:SourceArn: !Sub "arn:aws:bedrock-agentcore:${AWS::Region}:${AWS::AccountId}:*"
Policies:
- PolicyName: agent-runtime-permissions
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ecr:GetAuthorizationToken
- ecr:BatchCheckLayerAvailability
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
Resource: "*"
- Effect: Allow
Action:
- bedrock:InvokeModel
- bedrock:InvokeModelWithResponseStream
Resource:
- "arn:aws:bedrock:*::foundation-model/*"
- "arn:aws:bedrock:*:*:inference-profile/*"
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
# --- EC2インスタンスにアタッチするインスタンスプロファイルロール(システムログ収集用) ---
InstanceProfileRole:
Type: AWS::IAM::Role
Properties:
RoleName: agentcore-instances-instance-profile-role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- !Ref InstanceProfileRole
# --- AgentCoreがEC2をプロビジョニング/管理するためのロール(Capacity Provider Operator Role) ---
CapacityProviderOperatorRole:
Type: AWS::IAM::Role
Properties:
RoleName: agentcore-capacity-provider-operator-role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: bedrock-agentcore.amazonaws.com
Action: sts:AssumeRole
Condition:
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
ArnLike:
aws:SourceArn: !Sub "arn:aws:bedrock-agentcore:${AWS::Region}:${AWS::AccountId}:*"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/BedrockAgentCoreRuntimeInstancesOperatorRolePolicy
Policies:
- PolicyName: pass-instance-profile-role
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: iam:PassRole
Resource: !GetAtt InstanceProfileRole.Arn
Condition:
StringEquals:
iam:PassedToService: ec2.amazonaws.com
# --- Capacity Provider(EC2のOS・インスタンスタイプ・ネットワーク・ストレージを定義) ---
MyCapacityProvider:
Type: AWS::BedrockAgentCore::CapacityProvider
Properties:
Name: my_capacity_provider
Description: "AgentCore Runtime Instances 検証用"
PermissionsConfiguration:
CapacityProviderOperatorRoleArn: !GetAtt CapacityProviderOperatorRole.Arn
ComputeConfiguration:
Ec2Configuration:
LaunchTemplateSource:
LaunchParameters:
OperatingSystem: LINUX_X86_64
InstanceProfileArn: !GetAtt InstanceProfile.Arn
InstanceRequirements:
AllowedInstanceTypes:
- m5.large
Monitoring: BASIC
VpcConfiguration:
Subnets:
- !Ref SubnetId
SecurityGroups:
- !Ref SecurityGroupId
Volumes:
- EbsConfiguration:
Name: scratch
SizeGiB: 8
VolumeType: gp3
Encrypted: true
# --- Agent Runtime(Capacity Providerに紐付けてInstancesで動かす) ---
MyAgentRuntime:
Type: AWS::BedrockAgentCore::Runtime
DependsOn: MyCapacityProvider
Properties:
AgentRuntimeName: my_instances_agent
RoleArn: !GetAtt AgentRuntimeExecutionRole.Arn
AgentRuntimeArtifact:
ContainerConfiguration:
ContainerUri: !Ref ContainerImageUri
CapacityProviderConfiguration:
CapacityProviderArn: !GetAtt MyCapacityProvider.Arn
FilesystemConfigurations:
- CapacityProviderVolume:
VolumeName: scratch
MountPath: /mnt/scratch
Outputs:
CapacityProviderArn:
Value: !GetAtt MyCapacityProvider.Arn
CapacityProviderId:
Value: !GetAtt MyCapacityProvider.CapacityProviderId
AgentRuntimeArn:
Value: !GetAtt MyAgentRuntime.AgentRuntimeArn
Step4: スタックをデプロイする
# テンプレートの構文チェック
aws cloudformation validate-template \
--template-body file://template.yaml
# デプロイ(SubnetId・SecurityGroupId・ContainerImageUriは自分の環境の値に置き換える)
aws cloudformation deploy \
--template-file template.yaml \
--stack-name agentcore-runtime-instances-demo \
--parameter-overrides \
SubnetId=subnet-0123456789abcdef0 \
SecurityGroupId=sg-0123456789abcdef0 \
ContainerImageUri=111122223333.dkr.ecr.ap-northeast-1.amazonaws.com/my-agent:latest \
--capabilities CAPABILITY_NAMED_IAM
AgentCore コンソール「ランタイム」ページの「キャパシティプロバイダー」タブで、作成した キャパシティプロバイダー が アクティブになっていることを確認しておきます。

キャパシティプロバイダーの詳細画面で、「関連ランタイム」に関連するランタイムが紐付いていることも確認しておきます。

Step5: エージェントを呼び出す
boto3 から直接叩いてサクッと動作確認しておきましょう。runtimeSessionId は 33 文字以上必要で、同じ ID を使い回すと同じセッション(=同じ EC2 インスタンス)にルーティングされます。
import boto3
import json
client = boto3.client("bedrock-agentcore", region_name="ap-northeast-1")
response = client.invoke_agent_runtime(
agentRuntimeArn="arn:aws:bedrock-agentcore:ap-northeast-1:123456789012:runtime/my_instances_agent-xxxxx",
runtimeSessionId="qiita-verification-session-000000000000", # 33文字以上
payload=json.dumps({"prompt": "こんにちは。自己紹介してください"}).encode(),
qualifier="DEFAULT",
)
print("Agent response:", json.loads(response["response"].read()))
初回の Invoke では EC2 インスタンスの起動が走るため、通常の microVM 呼び出しよりレイテンシが大きくなります。実測では初回が約 67 秒、起動済みインスタンスへの 2 回目以降の呼び出しは 1 秒前後でした。
EC2 コンソールの「インスタンス」からは管理対象として表示されていることが確認できます。

後片付け
Instances 方式は EC2 実費が発生し続けるので、検証が終わったら忘れずに削除します。
# スタックごと削除(Runtime→Capacity Providerの順に削除される)
aws cloudformation delete-stack \
--stack-name agentcore-runtime-instances-demo
気をつけるポイント・注意点
- コンピュートタイプは後から変更不可: Runtime を microVM と Instances の間で切り替えることはできません。作り直しになります
- 同一インスタンス上のエージェントは互いに隔離されない: 同じセッションに載る複数のエージェントはファイルシステムを共有し、コンテナ間・プロセス間の分離境界はありません。信頼できるエージェント同士でのみ同居する必要があります
-
マルチテナント時のセッションルーティングに注意:
InvokeAgentRuntimeはRuntime単位で認可され、runtimeSessionIdが呼び出し元に紐づいているかまでは検証されません。1つのIAMプリンシパルで複数エンドユーザーを裏側から呼び出す構成では、アプリ側でセッションIDとユーザーの対応を厳密に管理する必要があります -
料金は EC2 実費+管理コスト: microVM のような従量課金 1 本ではなく、EC2 インスタンス・EBS ボリュームの実費に加えて AgentCore の管理コストがかかります。長時間起動しっぱなしにするとコストが積み上がるので、アイドルタイムアウト(
LifecycleConfiguration)の設定を検討してください
