7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Bedrock AgentCore RuntimeはCDKでらくらくデプロイ!コンテナいらずでHot swapも可能!!

Posted at

Bedrock AgentCoreはコンテナでデプロイするものとばかり思ってましたが、気がつけばS3を経由したZip形式でのデプロイにも対応してました。

そしてCDKでもすでにこの方式を使ったデプロイが可能です。

私は普段WinodwsとWSL環境を使っているのですが、arm64向けのコンテナイメージを作成する際に毎回ハマってしまうで、CDKを使ってコンテナなしでデプロイする方法を検証しました。

さらにさらに、Hot swapもできるのでもう無敵ですね!

こちらに検証に使ったソース一式を格納しています。

エージェントを作成

uv init agent --python 3.13
cd agent

生成されるファイルはこんな感じ

tree -a -I .git
.
├── .gitignore
├── main.py
├── pyproject.toml
├── .python-version
└── README.md

1 directory, 5 files

Strands AgentsとBedrock AgentCore SDKを追加します。

uv add strands-agents bedrock-agentcore

main.pyにエージェントを実装します。エージェントの内容を主題じゃないので最低限です。

main.py
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from strands import Agent

app = BedrockAgentCoreApp()


@app.entrypoint
async def invoke(payload):
    agent = Agent(
        model="openai.gpt-oss-120b-1:0",
        system_prompt="""
            You are a helpful assistant.
        """,
    )

    stream = agent.stream_async(payload.get("prompt"))

    async for event in stream:
        if "data" in event and isinstance(event["data"], str):
            yield event["data"]


if __name__ == "__main__":
    app.run()

ローカルで動作確認します。

Shell1
uv run main.py
Shell2
curl -X POST http://localhost:8080/invocations \
  -H "Content-Type: application/json" \
  -d '{"prompt": "What is artificial intelligence?"}'

それっぽい返事が返ってきたら成功です。

ダイレクトコードデプロイの準備

今回はコンテナを使わず、ダイレクトコードデプロイの手順でデプロイを行います。

AgentCore Runtimeの環境はCPUアーキテクチャがarm64です。WindowsのWSL環境の場合、CPUアーキテクチャが異なるのでarm64向けのPythonライブラリーを別途取得する必要があります。

agentディレクトリで、以下のコマンドを実行し、arm64向けのPythonライブラリーを取得します。

uv pip install \
  --python-platform aarch64-manylinux2014 \  # `arm64のLinux向け`を指定
  --python-version 3.13 \  # Pythonのバージョンを指定
  --target=deployment_package \  # ダウンロード先のディレクトリを指定。(名称は任意)
  --only-binary=:all: \  # ソースコードからビルドせずプリビルドの.whlを使用するよう指定
  -r pyproject.toml  # 取得対象のライブラリーを記載したpyproject.tomlを指定

実行するとこんな構成となり、.venv内がローカル(amd64)で使用する仮想環境(ライブラリーを含む)で、deployment_package内がAgentCore Runtime(arm64)で使用するライブラリーが含まれます。

tree -a -I .git -L 1
.
├── deployment_package  # AgentCore Runtime環境で使用するライブラリー
├── .gitignore
├── main.py
├── pyproject.toml
├── .python-version
├── README.md
├── uv.lock
└── .venv  # ローカル環境で使用する仮想環境(ライブラリーを含む)

3 directories, 6 files

手動でデプロイする場合は引き続き以下の手順が必要ですが、このあたりが面倒なのでCDKでやることにします。

  1. ライブラリーをZipに圧縮する
  2. main.pyをZipに追加する
  3. S3にアップロードする
  4. マネコン or CLIでAgentCoreを更新する

CDKを作成

CDKでデプロイする準備を行います。
agentディレクトリと横並びにcdkディレクトリを作って始めます。

mkdir cdk
cd cdk

cdk initで必要なファイルを生成します。

npx -y cdk init app --language typescript

生成されるファイルはこんな感じです。

tree -a -I node_modules -I .git
.
├── bin
│   └── cdk.ts
├── cdk.json
├── .gitignore
├── jest.config.js
├── lib
│   └── cdk-stack.ts
├── .npmignore
├── package.json
├── package-lock.json
├── README.md
├── test
│   └── cdk.test.ts
└── tsconfig.json

4 directories, 11 files

BedrockとBedrock AgentCoreのConstruct Libraryはアルファなので(?)追加で導入します。

npm i @aws-cdk/aws-bedrock-alpha @aws-cdk/aws-bedrock-agentcore-alpha

cdk/lib/cdk-stack.tsに実装していきます。

まず、S3にアップロードするアセットを定義します。先程arm64向けのPythonライブラリーを取得したdeployment_packageディレクトリを相対パスで指定します。

aws-cdk-lib/aws-s3-assetsモジュールのAssetコンストラクトは、指定したディレクトリをZip圧縮してS3にアップロードしてくれます。ステキ!

cdk/lib/cdk-stack.ts
    // S3にアップロードするアセットを定義
    const asset = new Asset(this, 'CodeAsset', {
      path: path.join(__dirname, '../../agent/deployment_package'),
    });

続いてAgentCore Runtimeのアーティファクトを定義します。引数は順にs3Location、runtime、entrypointです。

cdk/lib/cdk-stack.ts
    // AgentCore Runtimeのアーティファクトを定義
    const artifact = AgentRuntimeArtifact.fromS3(
      {
        bucketName: asset.s3BucketName,
        objectKey: asset.s3ObjectKey,
      },
      AgentCoreRuntime.PYTHON_3_13,
      ['main.py'],
    );

そしてAgentCore Runtimeを定義します。

cdk/lib/cdk-stack.ts
    // AgentCore Runtimeを定義
    const agentRuntime = new Runtime(this, 'agent', {
      runtimeName: 'sample_agent',
      agentRuntimeArtifact: artifact,
      description: 'Sample agent',
    });

このままではBedrockへアクセスができないので、Bedrockの使用するモデルへの権限を付与します。

cdk/lib/cdk-stack.ts
    // AgentCore Runtimeに対してBedrockへのアクセス権を付与
    const bedrockModel = BedrockFoundationModel.fromCdkFoundationModelId({
      modelId: "openai.gpt-oss-120b-1:0"
    });
    bedrockModel.grantInvoke(agentRuntime);

デプロイ時にmain.pyをコピーするスクリプトを追加

S3へアップロードされるアセットはdeployment_packageディレクトリのため、このままでは肝心のmain.pyが含まれません。ローカル環境でのデバッグ時には.venvと同じディレクトリにmain.pyが必要なので移動はしたくありません。

そこで、現在の配置は維持しつつ、デプロイの際にdeployment_packageディレクトリへコピーする方法を考えました。

これを実現するために、package.jsonのscriptsとして以下の3つを追加します。スクリプトの名称にpreをつけると、該当のスクリプトを実行する前に自動的に実行されます。

package.json
  "scripts": {
    "build": "tsc",
    "watch": "tsc -w",
    "test": "jest",
-   "cdk": "cdk"
+   "cdk": "cdk",
+   "agent:sync": "cp ../agent/main.py ../agent/deployment_package/",
+   "predeploy": "npm run agent:sync",
+   "deploy": "cdk deploy"
  },

この設定の状態で、npm run deployを実行すると、まずpredeployが呼ばれそのスクリプトとして更にagent:syncが呼ばれます。結局のところ、cdk deployの際には必ずmain.pyが所定の位置にコピーされるという作戦です。

$ npm run deploy

> cdk@0.1.0 predeploy
> npm run agent:sync


> cdk@0.1.0 agent:sync
> cp ../agent/main.py ../agent/deployment_package/


> cdk@0.1.0 deploy
> cdk deploy

その気になれば、arm64ライブラリーを取得するところもスクリプトに登録可能です。

"agent:install-arm64": "cd ../agent && uv pip install --python-platform aarch64-manylinux2014 --python-version 3.13 --target=deployment_package --only-binary=:all: -r pyproject.toml"

npm run deployするだけでいい

これでnpm run deployするとコンテナを使わず簡単にデプロイできます。

マネコンのサンドボックスで動作も確認できました。

やったね!

さらにHot swapも対応

さらにCDKを使うと、AgentCore RuntimeのHot swapデプロイも可能です。

詳細はこちら(素敵な機能をありがとうございます!)

package.jsonのscriptsにHot swap用の設定を追加したら完璧です。

package.json
  "scripts": {
    "build": "tsc",
    "watch": "tsc -w",
    "test": "jest",
    "cdk": "cdk",
    "agent:sync": "cp ../agent/main.py ../agent/deployment_package/",
    "predeploy": "npm run agent:sync",
-   "deploy": "cdk deploy"
+   "deploy": "cdk deploy",
+   "predeploy:hotswap": "npm run agent:sync",
+   "deploy:hotswap": "cdk deploy --hotswap"
  },

main.pyに修正を加えて、deploy:hotswapして時間を計測してみました。

$ time npm run deploy:hotswap

> cdk@0.1.0 predeploy:hotswap
> npm run agent:sync


> cdk@0.1.0 agent:sync
> cp ../agent/main.py ../agent/deployment_package/


> cdk@0.1.0 deploy:hotswap
> cdk deploy --hotswap


✨  Synthesis time: 12.62s

⚠️ The --hotswap and --hotswap-fallback flags deliberately introduce CloudFormation drift to speed up deployments
⚠️ They should only be used for development - never use them for your production Stacks!

CdkStack: start: Building CodeAsset
CdkStack: success: Built CodeAsset
CdkStack: start: Building CdkStack Template
CdkStack: success: Built CdkStack Template
CdkStack: start: Publishing CodeAsset (current_account-current_region-bff99a57)
CdkStack: start: Publishing CdkStack Template (current_account-current_region-2c072784)
CdkStack: success: Published CdkStack Template (current_account-current_region-2c072784)
CdkStack: success: Published CodeAsset (current_account-current_region-bff99a57)
CdkStack: deploying... [1/1]

✨ hotswapping resources:
   ✨ AWS::BedrockAgentCore::Runtime 'sample_agent-fNrc4OBgX0'
   ✨ AWS::BedrockAgentCore::Runtime 'sample_agent-fNrc4OBgX0' hotswapped!

✨  hotswap-deployment time: 3.28s


 ✅  CdkStack

✨  Deployment time: 7.58s

Stack ARN:
arn:aws:cloudformation:us-east-1:123456789012:stack/CdkStack/9464e2e0-fa51-11f0-8c01-12814a71a721

✨  Total time: 20.2s

real    0m48.344s
user    0m13.682s
sys     0m8.216s

Hot swapが適用され、なんと48秒で再デプロイ完了です!

神!!

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?