気がついたら、Amazon Bedrock AgentCore Runtime のデプロイツールを作ってしまっていた話

こんにちは! カヤックのグループ情報部の@mashiikeです。
この記事は面白法人グループ Advent Calendar 2025の19日目の記事です。

Amazon Bedrock AgentCore Runtime とは?

さて、世の中はAI Agents時代で、様々なAgentが日進月歩で開発されていると思います。
そうなってくると、クラウドベンダーは AI Agent向けやMCP(Model Context Protocol)サーバー向けのプラットフォームを提供し始めるのが世の常なのかもしれません。 こんな背景を話すと当然出てくるのが、 Amazon Web Services(AWS)から登場したAmazon Bedrock AgentCoreです。

aws.amazon.com

AgentCoreにはAI Agentを構築するために便利な機能がいくつも提供されていますが、その中で今回注目したいのがAgentCore Runtimeです。 このAgentCore RuntimeはAmazon ECSやAWS Lambdaに続く新しいコンピューティング基盤となります。

AgentCore Runtimeの魅力

使ってみると色々と便利ですが、個人的に魅力な点を1点上げるならば、インスタンスライフサイクルの柔軟性 にあると思います。
細かい話はドキュメントとかを見ていただきたいのですが、ざっくりと一言で言うなら AWS Lambdaより長く動くし、ECSよりむっちゃサーバレスで、Session Stickyな実行環境 という感じです。

/ping Endpointを実装して、そこで{"status":"HealthBusy",...}と返し続ければ、最大で8時間も動きます。
さらに、idleRuntimeSessionTimeoutの設定を1分という短い時間に設定すると、/ping Endpointで {"status":"Healthy",...} と1分間返し続けるとインスタンスが落ちるという感じになります。
もちろん、idleRuntimeSessionTimeoutを長くすれば、インスタンスが落ちるまでの時間も長くなります。
使っている感触は、コールドスタートのコントロールがしやすいコンテナLambdaのようなイメージです。

AgentCore RuntimeのGet startedで・・・ あれ?

試しに使ってみるために公式のGet started with the AgentCore Runtimeを覗いてみましょう。

docs.aws.amazon.com

Prerequisites
Before you start, make sure you have:
AWS Account with credentials configured. To configure your AWS credentials, see Configuration and credential file settings in the AWS CLI.
Python 3.10+ installed
Boto3 installed AWS Permissions: To create and deploy an agent with the starter toolkit, you must have appropriate permissions. For information, see Use the starter toolkit. Model access: Anthropic Claude Sonnet 4.0 enabled in the Amazon Bedrock console. For information about using a different model with the Strands Agents see the Model Providers section in the Strands Agents SDK documentation.

な・・・なるほど・・・?。
そうですよね。AIといえばPythonですよね。
とはいえ、今作っているものはgoとtypescriptで動いているんですよね・・・。
そうは言いつつ、一旦toolkitを見てみよう!  

$ agentcore deploy --help
                                                                                                                                  
 Usage: agentcore deploy [OPTIONS]                                                                                                
                                                                                                                                  
 Deploy Bedrock AgentCore with three deployment modes (formerly 'launch').                                                        
                                                                                                                                  
 🚀 DEFAULT (no flags): Cloud runtime (RECOMMENDED)                                                                               
    - direct_code_deploy deployment: Direct deploy Python code to runtime                                                         
    - Container deployment: Build ARM64 containers in the cloud with CodeBuild                                                    
    - Deploy to Bedrock AgentCore runtime                                                                                         
    - No local Docker required                                                                                                    
                                                                                                                                  
 💻 --local: Local runtime                                                                                                        
    - Container deployment: Build and run container locally (requires Docker/Finch/Podman)                                        
    - direct_code_deploy deployment: Run Python script locally with uv                                                            
    - For local development and testing                                                                                           
                                                                                                                                  
 🔧 --local-build: Local build + cloud runtime                                                                                    
    - Build container locally with Docker                                                                                         
    - Deploy to Bedrock AgentCore runtime                                                                                         
    - Only supported for container deployment type                                                                                
    - requires Docker/Finch/Podman                                                                                                
    - Use when you need custom build control but want cloud deployment                                                            
                                                                                                                                  
 MIGRATION GUIDE:                                                                                                                 
 - OLD: agentcore launch --code-build  →  NEW: agentcore deploy                                                                   
 - OLD: agentcore launch --local       →  NEW: agentcore deploy --local (unchanged)                                               
 - NEW: agentcore deploy --local-build (build locally + deploy to cloud)                                                          
                                                                                                                                  
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --agent                    -a        TEXT  Agent name (use 'agentcore configure list' to see available agents)                 │
│ --local                    -l              Run locally for development and testing                                             │
│ --local-build              -lb             Build locally and deploy to cloud (container deployment only)                       │
│ --auto-update-on-conflict  -auc            Automatically update existing agent instead of failing with ConflictException       │
│ --force-rebuild-deps       -frd            Force rebuild of dependencies even if cached (direct_code_deploy deployments only)  │
│ --env                      -env      TEXT  Environment variables for agent (format: KEY=VALUE)                                 │
│ --help                                     Show this message and exit.                                                         │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

なるほど、containerでも行けるのか〜。でもローカル環境Dockerじゃないんだよなぁ・・・。

気がついたら、デプロイツールを作ってしまっていた話

さて、toolkit を触り始めてみると、どうやらPython前提っぽいし、containerもローカルではDockerが必要っぽいことがわかりました。
そこで、マネージメントコンソールの方を覗いてみると、以下のようにECRにpushされていれば良さそうなので、とりあえずはコンソールからデプロイしてお試しできました。

AWSのコンソール

しばらくして、以下のようなスクリプトが生まれました。

#!/bin/bash
AGENT_RUNTIME_ID="${1:?Agent runtime ID is required}"
CONTAINER_URI="${2:?Container URI is required}"

echo "deploying AgentCore Runtime... agent-runtime-id=$AGENT_RUNTIME_ID, container-uri=$CONTAINER_URI"

aws bedrock-agentcore-control update-agent-runtime --generate-cli-skeleton  > input_template.json

aws bedrock-agentcore-control get-agent-runtime --agent-runtime-id $AGENT_RUNTIME_ID > current_agent_runtime.json

jq -s '
  .[0] as $A
  | .[1] as $B
  | reduce ($A | keys[]) as $k ({};
      if $B | has($k) then .[$k] = $B[$k] else . end
    )
' input_template.json current_agent_runtime.json | jq --arg uri "$CONTAINER_URI" '
  .agentRuntimeArtifact.containerConfiguration.containerUri = $uri
' > updated_agent_runtime.json

cat updated_agent_runtime.json

aws bedrock-agentcore-control update-agent-runtime --cli-input-json file://./updated_agent_runtime.json

このスクリプトは、ECRにpushしたコンテナURIを指定して、既存のAgentCore Runtimeを更新するだけのものです。 そして、このスクリプトを使っているうちに、ふと思いました。

「ここまでやったら、lambrollecspresso のような感覚でデプロイ出来るようにしたいなぁ・・・」と。

github.com github.com

そして、気がついたらデプロイツールを作ってしまっていた というわけです。

出来上がったツールはこちらです。

github.com

このツールでは、インフラ周りも他のAgentCoreの機能も触りません。 コンテナもECRにpush済みという想定です。とにかくシンプルにAgentCore Runtimeのデプロイだけに特化しています。
基本的な思想は、きっかけ通り lambrollecspresso を真似ているはずです。

使い方

ecspressolambroll を使ったことがある人は、きっと馴染み深いと思いますが、設定ファイルはjsonnetで記述します。 最初から書くのは大変だと思うので、マネージメントコンソールでポチポチと作って、acrun init で設定ファイルを生成するのが良いと思います。

インストールはリリースバイナリを落とすか、 aquaのregistryに入れてもらったのでaqua経由で入れるのがいいと思います。
※ 一応brewのtapも用意してますが、更新忘れがちなので個人的にはaqua経由かバイナリインストールがおすすめです。

$ aqua init 
$ aqua g -i -s mashiike/acrun
$ aqua exec -- acrun version
acrun v0.7.0
$ aqua exec -- acrun init --agent-name <your-agent-runtime-name>
time=2025-12-16T15:07:00.925+09:00 level=INFO msg="fetched AgentRuntime" name=test arn=arn:aws:bedrock-agentcore:<region>:<your-account-id>:runtime/<your-agent-runtime-id>
time=2025-12-16T15:07:00.930+09:00 level=INFO msg="createing agent runtime file" file=agent_runtime.jsonnet

これで agent_runtime.jsonnet という設定ファイルが生成されます。中身を見ると以下のようになっています。

{
  agentRuntimeArtifact: {
    containerConfiguration: {
      containerUri: '<account_id>.dkr.ecr.<region>.amazonaws.com/acrun/test:latest',
    },
  },
  agentRuntimeName: 'test',
  authorizerConfiguration: {
    customJWTAuthorizer: {
      allowedAudience: [
        '<your-client-audience>',
      ],
      discoveryUrl: 'https://accounts.google.com/.well-known/openid-configuration',
    },
  },
  lifecycleConfiguration: {
    idleRuntimeSessionTimeout: 60,
    maxLifetime: 28800,
  },
  networkConfiguration: {
    networkMode: 'PUBLIC',
  },
  protocolConfiguration: {
    serverProtocol: 'HTTP',
  },
  roleArn: 'arn:aws:iam::<your-account-id>:role/AmazonBedrockAgentCoreRuntimeDefaultServiceRole',
}

jsonnetのnative_functionsは基本的には主にlambrollを参考に実装しています。ですので、以下のように書き換えることができます。 もちろんTerraformのStateFileからの参照も一応対応しています。

local caller = std.native('callerIdentity')();
local env = std.native('env');
local mustEnv = std.native('mustEnv');

{
  agentRuntimeArtifact: {
    containerConfiguration: {
      containerUri: '%s.dkr.ecr.%s.amazonaws.com/acrun/test:latest' % [caller.account, env('AWS_REGION', 'us-east-1')],
    },
  },
  agentRuntimeName: 'test',
  authorizerConfiguration: {
    customJWTAuthorizer: {
      allowedAudience: [
        mustEnv('GOOGLE_CLIENT_AUDIENCE'),
      ],
      discoveryUrl: 'https://accounts.google.com/.well-known/openid-configuration',
    },
  },
  lifecycleConfiguration: {
    idleRuntimeSessionTimeout: 60,
    maxLifetime: 28800,
  },
  networkConfiguration: {
    networkMode: 'PUBLIC',
  },
  protocolConfiguration: {
    serverProtocol: 'HTTP',
  },
  roleArn: 'arn:aws:iam::%s:role/AmazonBedrockAgentCoreRuntimeDefaultServiceRole' % [caller.account],
}

deployはECRにコンテナをpushしたあとにデプロイすればいい感じです。

$ aqua exec -- acrun deploy

デプロイツール作成周りで工夫した点

lambrollecspressoも、設定ファイルは基本的にはLambda CreateFunction APIECS RegisterTaskDefinition APIのペイロードをベースに作っています。 この辺の話はfujiwaraさんの今年のYAPC Fukuokaのスライドを見ていただくと思想がよくわかると思います。

speakerdeck.com

この思想はとても良いと思っているので、github.com/mashiike/acrun でも、設定ファイルはAmazon Bedrock AgentCore Control Plane CreateAgentRuntime APIのペイロードをベースに作ろうと思いました。

acrun は Goで実装しているので、SDKの対応する型はCreateAgentRuntimeInput になります。 この型をベースで設定ファイルを作れば、lambrollecspressoと同様にGoのSDKのバージョンアップすれば新機能に素早く対応できるというメリットがあります。

おわりに

新しく登場した Amazon Bedrock AgentCore Runtimeをお試ししている間に、気がついたらデプロイツールを作ってしまった話をしました。 もし、lambrollecspresso のような感覚でAgentCore Runtimeをデプロイしたい人がいましたら、ぜひ使ってみてください。 作った感想としては、CodingAgentの登場によって、デプロイツールもすんなりと作れるようになったなぁと感じました。

カヤックでは、気がついたらデプロイツールを作ってしまうエンジニアも募集してるかもしれません。