AWS Strands AgentsをAmazon Bedrock AgentCoreにCloudFormationでデプロイしてみた

に公開

はじめ

Fusicのレオナです。今回は、Amazon Bedrock AgentCoreにStrands AgentsをCloudFormationでデプロイし、Strands Agentsを動作させる方法について解説します

注意:本ブログは 2025年10月1日時点の機能を基に執筆しています。Amazon Bedrock AgentCoreはプレビュー版です。


Strands Agentsとは

Strands Agentsは、AWSが2025年5月に公開したオープンソースのAIエージェント構築SDKで、2025年7月にバージョン1.0がリリースされました。数行のPythonコードでAIエージェントを作成できるモデル駆動型のフレームワークです。

ベータ版のStrands Agentsについて執筆した以下のブログも参考にしてください。
https://zenn.dev/fusic/articles/8dd670c37a8d68

また本ブログではStrands AgentsのTools(ツール)を用いて動作確認を行います。Toolsは、ベースのLLM単体ではできない処理を呼び出せる機能です。AIエージェントがAPIを通して外部機能やサービスを呼び出すことができます。

今回はコミュニティ製のCalculatorツールを使用します。

https://strandsagents.com/latest/documentation/docs/user-guide/concepts/tools/community-tools-package/
https://github.com/strands-agents/tools/blob/main/src/strands_tools/calculator.py

Amazon Bedrock AgentCoreとは

Amazon Bedrock AgentCoreは2025年7月にプレビュー版が公開されたサービスで、AIエージェントを AWS上にホストするフルマネージド実行環境です。
https://aws.amazon.com/jp/bedrock/agentcore/

実装

今回作成するリポジトリは以下のような構成になります:

calc-agent/
├── src/
│   ├── agent.py          # Strands Agent定義
│   └── server.py         # BedrockAgentCoreApp
├── cfn/
│   └── template.yaml     # CloudFormationテンプレート
├── .env                  # 環境変数(自動生成)
├── .gitignore
├── deploy.sh             # デプロイスクリプト
├── Dockerfile            # ARM64コンテナ
├── requirements.txt      # ECRにPushされる Python依存関係
└── test_calc_agent.py    # テストスクリプト

事前準備

  • AWS CLI v2.31.5以降(aws --versionで確認)
  • Docker
  • Python3.11以降と動かす環境(uv等)
    • pip install boto3 python-dotenvでライブラリをインストールする
      • Amazon Bedrock AgentCoreにデプロイしたStrands Agentsをローカルから呼び出すために必要になります。

1. src/agent.py

Strands AgentsのAgentを定義します。Calculatorツールを読み込み、プロンプトを定義しています。

agent.py
from strands import Agent
from strands_tools import calculator

SYSTEM_PROMPT = """You are a precise math assistant.
Use the calculator tool for any non-trivial arithmetic.
Return a short final answer. Include units if provided."""

def create_agent(model_id: str | None = None) -> Agent:
    model = model_id or None
    return Agent(system_prompt=SYSTEM_PROMPT, tools=[calculator], model=model)

2. src/server.py

Amazon Bedrock AgentCoreのHTTPプロトコルでは、エントリーポイントだけ実装すれば同期呼び出しが可能です。ここではBedrockAgentCoreAppを使ってStrands Agentsを呼び出します。

server.py
import os
from bedrock_agentcore import BedrockAgentCoreApp
from src.agent import create_agent

app = BedrockAgentCoreApp()
agent = create_agent(model_id=os.environ.get("MODEL_ID"))


@app.entrypoint
def invoke(payload):
    """エージェントのエントリーポイント"""
    prompt = payload.get("prompt", "")
    result = agent(prompt)
    return {"response": str(result)}


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

3. cfn/template.yaml

実行ロールとエージェントランタイムリソースを定義します。ContainerUriにECRのイメージURIを渡すことでデプロイできます。

template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Strands Calculator Agent on Amazon Bedrock AgentCore (HTTP)

Parameters:
  AgentName:
    Type: String
    Default: strands_calc
    Description: Name of the agent runtime (alphanumeric and underscore only)
  ContainerUri:
    Type: String
    Description: "<account-id>.dkr.ecr.<region>.amazonaws.com/<repo>:<tag> or @sha256:..."

Resources:
  AgentCoreExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${AgentName}-runtime-role
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: bedrock-agentcore.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: EcrLogsBedrockInvoke
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              # ECR pull
              - Effect: Allow
                Action: ecr:GetAuthorizationToken
                Resource: "*"
              - Effect: Allow
                Action:
                  - ecr:BatchGetImage
                  - ecr:GetDownloadUrlForLayer
                Resource: !Sub arn:aws:ecr:${AWS::Region}:${AWS::AccountId}:repository/*
              # CloudWatch Logs
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - logs:DescribeLogGroups
                  - logs:DescribeLogStreams
                Resource: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/bedrock-agentcore/runtimes/*:*
              # Bedrock モデル呼び出し(foundation model + inference profile)
              - Effect: Allow
                Action:
                  - bedrock:InvokeModel
                  - bedrock:InvokeModelWithResponseStream
                Resource:
                  - arn:aws:bedrock:*::foundation-model/*
                  - arn:aws:bedrock:*:*:inference-profile/*

  CalcAgentRuntime:
    Type: AWS::BedrockAgentCore::Runtime
    Properties:
      AgentRuntimeName: !Ref AgentName
      AgentRuntimeArtifact:
        ContainerConfiguration:
          ContainerUri: !Ref ContainerUri
      ProtocolConfiguration: HTTP
      RoleArn: !GetAtt AgentCoreExecutionRole.Arn
      NetworkConfiguration:
        NetworkMode: PUBLIC
      EnvironmentVariables:
        MODEL_ID: "us.anthropic.claude-sonnet-4-20250514-v1:0"
        CALCULATOR_PRECISION: "10"

Outputs:
  AgentRuntimeId:
    Value: !GetAtt CalcAgentRuntime.AgentRuntimeId
    Description: The ID of the agent runtime
  AgentRuntimeArn:
    Value: !GetAtt CalcAgentRuntime.AgentRuntimeArn
    Description: The ARN of the agent runtime
  AgentRuntimeVersion:
    Value: !GetAtt CalcAgentRuntime.AgentRuntimeVersion
    Description: The version of the agent runtime

4. deploy.sh

ECRリポジトリの作成、コンテナのビルドとプッシュ、CloudFormationスタックのデプロイをまとめて行うシェルスクリプトになります。最後に.envファイルに ARN などを保存します
またdeploy.shではAWS CLIを使います。PROFILEを自分のプロファイル名を指定してください。

以下の作業が./deploy.shで行われます。

  1. ECRリポジトリ作成 : strands-calcという名前のリポジトリを作成
  2. Dockerイメージビルド : ARM64プラットフォーム向けにビルド
  3. ECRログイン : AWS認証情報でECRにログイン
  4. イメージプッシュ : ビルドしたイメージをECRにアップロード
    5.CloudFormationデプロイ : cfn/template.yamlを使ってインフラをデプロイ
  5. 環境変数ファイル生成 : デプロイ後のARNなどを.envファイルに保存
deploy.sh
#!/bin/bash
set -e

# 設定
PROFILE="" # 自分のプロファイル
REGION="us-west-2"
ACCOUNT_ID=$(aws sts get-caller-identity --profile $PROFILE --query Account --output text)
REPO_NAME="strands-calc"
AGENT_NAME="strands_calc"
STACK_NAME="strands-calc-agent"

echo "=== ECR リポジトリの作成 ==="
aws ecr create-repository --repository-name $REPO_NAME --region $REGION --profile $PROFILE || true

echo "=== Docker イメージのビルド(ARM64) ==="
docker buildx build --platform linux/arm64 \
  --progress=plain \
  -t $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:latest \
  .

echo "=== ECR ログイン ==="
aws ecr get-login-password --region $REGION --profile $PROFILE \
  | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com

echo "=== Docker イメージのプッシュ ==="
docker push $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:latest

# タグ形式を使用
CONTAINER_URI="$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:latest"
echo "Container URI: $CONTAINER_URI"

echo "=== CloudFormation スタックのデプロイ ==="
aws cloudformation deploy \
  --template-file cfn/template.yaml \
  --stack-name $STACK_NAME \
  --parameter-overrides \
    AgentName=$AGENT_NAME \
    ContainerUri=$CONTAINER_URI \
  --capabilities CAPABILITY_NAMED_IAM \
  --region $REGION \
  --profile $PROFILE

echo "=== デプロイ完了 ==="
aws cloudformation describe-stacks \
  --stack-name $STACK_NAME \
  --region $REGION \
  --profile $PROFILE \
  --query 'Stacks[0].Outputs'

echo ""
echo "=== 環境変数ファイル生成 ==="
AGENT_ARN=$(aws cloudformation describe-stacks \
  --stack-name $STACK_NAME \
  --region $REGION \
  --profile $PROFILE \
  --query 'Stacks[0].Outputs[?OutputKey==`AgentRuntimeArn`].OutputValue' \
  --output text)

cat > .env << EOF
# Bedrock AgentCore Calculator Agent 環境変数設定
# このファイルは deploy.sh によって自動生成されます

# Agent Runtime ARN
AGENT_RUNTIME_ARN=$AGENT_ARN

# AWSリージョン
AWS_REGION=$REGION

# AWSプロファイル
AWS_PROFILE=$PROFILE
EOF

echo "✅ .env ファイルを作成しました"

5. Dockerfile

Dockerfile
FROM python:3.11-slim
ENV PYTHONUNBUFFERED=1
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY src/ ./src/
EXPOSE 8080
CMD ["python", "-m", "src.server"]

6. requirements.txt

ECRにPushされるrequirements.txtPython依存関係になります。

requirements.txt
bedrock-agentcore
strands-agents>=1.0.0
strands-agents-tools>=0.2.0

7. test_calc_agent.py

デプロイしたエージェントを呼び出して動作確認するためのスクリプトです。.envを読み込み、計算させたい式をプロンプトとして送信します。

test_calc_agent.py
import boto3
import json
import sys
import os
import uuid
from dotenv import load_dotenv
load_dotenv()

def main():

    agent_runtime_arn = os.environ.get("AGENT_RUNTIME_ARN")
    region = os.environ.get("AWS_REGION")
    profile = os.environ.get("AWS_PROFILE")

    prompt = " ".join(sys.argv[1:])
    session = boto3.Session(profile_name=profile, region_name=region)
    client = session.client('bedrock-agentcore')

    response = client.invoke_agent_runtime(
        agentRuntimeArn=agent_runtime_arn,
        runtimeSessionId=f"session-{uuid.uuid4()}",
        payload=json.dumps({"prompt": prompt}).encode('utf-8'),
        qualifier="DEFAULT"
    )

    response_body = response['response'].read().decode('utf-8')
    response_data = json.loads(response_body)
    print(response_data.get('response', '').strip())


if __name__ == "__main__":
    """
    Usage: python test_calc_agent.py "Calculate 5 * 5"
    """
    main()

実行例

ルートディレクトリで以下のコマンドを実行する。`

./deploy.sh 2>&1 | tee deploy.log

デプロイが完了したらtest_calc_agent.pyでAgentCoreにデプロイされたStrands Agentsを呼び出します。

test_calc_agent.py "Calculate 5 * 5"

結果

Terminal
25

最後に

今回はCloudFormationを使ってStrands AgentsをAmazon Bedrock AgentCoreにデプロイすることができました。IaCでAmazon Bedrock AgentCoreにデプロイできるのがとても良い感じました。

Fusic 技術ブログ

Discussion