やりたいこと
Step Functions(以下SFn)のワークフロー内でBedrockを呼び出したい。
でも東京リージョンのコンソール上で確認すると、利用可能なモデルがなんだか少ない…
せっかくなら最新版のClaude Sonnet 4など、より優れたモデルを使いたいですよね。
表示されるモデルが少ない原因
これの原因は、恐らく東京リージョンのみで使用可能な基盤モデルが表示されているためです。
東京リージョンのみで利用可能なBedrock
まず、東京リージョンでのみ利用可能なBedrockを確認します。
Cross-region inferenceの記載があるものは、クロスリージョン推論でしか利用できないモデルとなっています。
以下ドキュメントにおいても、「一部のモデルは、一部のリージョンではクロスリージョン推論を通じてのみアクセスできます」と記載されています。
したがって、Anthropicのモデルで東京リージョンのみに閉じて利用できるのは
- Claude 3.5 Sonnet
- Claude3 Haiku
- Claude 2.1
- Claude Instant
の4つのみとなります。
SFnの仕様
また、SFnの仕様としてクロスリージョンリソースアクセスはできません。
現在、クロスリージョン AWS SDK 統合とクロスリージョン AWS リソースアクセスは Step Functions では使用できません。
したがって、クロスリージョンにリクエストを送信することになるモデルたちは、SFn上で選択できない・利用できないものだと思っていました。
クロスリージョン推論でしか使えないモデルを使う方法
と思い込んでいたのですが、意外とできました!それも結構簡単に!
やりかた
BedrockのInvokeModelをワークフロー上へ持ってきておきます。
2025/05/24現在、boto3などのAWS SDKでBedrockの基盤モデルを呼び出したい場合は、Converse APIというのを用いるのが主流だと思います。
ただ、現状SFnではInvokeModel APIしか使うことはできないようです。
モデルは仮として、Claude 3.5 Sonnetを選択しておきます。
コンソールにおいて「デザイン」ではなく「コード」を選択すると、先程のワークフローをコードで表現したものが出現します。
これは「Amazon States Language(以下ASL)」というJSONベースの構造化言語が用いられています。
{
"Comment": "A description of my state machine",
"StartAt": "Bedrock InvokeModel",
"States": {
"Bedrock InvokeModel": {
"Type": "Task",
"Resource": "arn:aws:states:::bedrock:invokeModel",
"Arguments": {
"ModelId": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0",
"Body": {
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 200,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "string"
}
]
}
]
}
},
"End": true
}
},
"QueryLanguage": "JSONata"
}
このModelId
の部分を、クロスリージョン対応のモデルIDに変えてあげます。
今回は最新版であるClaude Sonnet 4を指定してみましょう。
Bedrockコンソールの「Cross-region inference」ページを参照し、Inference profile IDもしくはARNをコピーし、先程のModelId
の値を置き換えます。
- "ModelId": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0"
// ↓どちらか一方だけでOKです
+ "ModelId": "apac.anthropic.claude-sonnet-4-20250514-v1:0"
+ "ModelId": "arn:aws:bedrock:ap-northeast-1:<アカウントID>:inference-profile/apac.anthropic.claude-sonnet-4-20250514-v1:0"
また、プロンプトを入力できるようにするための変更を行います。デフォルトのままだと「string」が毎回入力されるだけになっているためです。
JSONata構文 "{% <JSONata expression> %}"
を用いて、入力値 prompt
の値を渡せるようにしてみましょう。
以下のように修正します。
"content": [
{
"type": "text",
- "text": "string"
+ "text": "{% $states.input.prompt %}"
}
]
JSONataのパラメータの渡し方は以下の感じみたいです。詳しくはドキュメントを見てみてください。
最終的に完成したASLは以下の感じです。
{
"Comment": "A description of my state machine",
"StartAt": "Bedrock InvokeModel",
"States": {
"Bedrock InvokeModel": {
"Type": "Task",
"Resource": "arn:aws:states:::bedrock:invokeModel",
"Arguments": {
"ModelId": "apac.anthropic.claude-sonnet-4-20250514-v1:0",
"Body": {
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 200,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "{% $states.input.prompt %}"
}
]
}
]
}
},
"End": true
}
},
"QueryLanguage": "JSONata"
}
これで、クロスリージョン推論を通じてClaude Sonnet 4へプロンプトを投げることができるようになりました!👏
(余談:Arguments
の中身は、Claudeが提供するMessages APIの形式に則っています。詳しくは以下をご参照ください。)
権限設定
上記ステートマシンを作成すると、SFn用のIAMロールと、Bedrock(とX-rayも)へのアクセス権限の設定されたIAMポリシーが作成されます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Sid": "InvokeModel1",
"Action": [
"bedrock:InvokeModel"
],
"Resource": [
"arn:aws:bedrock:ap-northeast-1::foundation-model/apac.anthropic.claude-sonnet-4-20250514-v1:0"
]
}
]
}
ただ、これだけで実行するとアクセス権限エラーが出ます。
{
"cause": "User: <ロール名> is not authorized to perform: bedrock:InvokeModel on resource: arn:aws:bedrock:ap-northeast-1:<アカウントID>:inference-profile/apac.anthropic.claude-sonnet-4-20250514-v1:0 because no identity-based policy allows the bedrock:InvokeModel action (Service: BedrockRuntime, Status Code: 403, Request ID: hogehoge) (SDK Attempt Count: 1)",
"error": "Bedrock.AccessDeniedException",
"resource": "invokeModel",
"resourceType": "bedrock"
}
要するに、「arn:aws:bedrock:ap-northeast-1:<アカウントID>:inference-profile/apac.anthropic.claude-sonnet-4-20250514-v1:0」への実行権限がないぞ、と怒られています。
自動作成されたIAMロールに付与されていたのは、東京リージョンのSonnet 4に対する権限だけだったのですが、クロスリージョン推論を使用する場合は推論プロファイルへのアクセス権限を追加してあげる必要があります。
また、デフォルトで設定されていた東京リージョンのモデルARNもちょっと書き方がおかしいです。「apac.」が余計ですね。こちらも修正します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Sid": "InvokeModel1",
"Action": [
"bedrock:InvokeModel"
],
"Resource": [
- "arn:aws:bedrock:ap-northeast-1::foundation-model/apac.anthropic.claude-sonnet-4-20250514-v1:0"
+ "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-sonnet-4-20250514-v1:0"
+ "arn:aws:bedrock:ap-northeast-1:<アカウントID>:inference-profile/apac.anthropic.claude-sonnet-4-20250514-v1:0"
]
}
]
}
これでOK…な時もあるのですが、まだ完了ではありません。
クロスリージョン推論を用いる場合は、ルーティングされるすべてのリージョンにおけるSonnet 4へのアクセス権限を付与してあげる必要があります。
つまり東京リージョンで実行する場合は、アジアパシフィックに所属し、かつSonnet 4を利用できるすべてのリージョンに対する権限を付与する必要があります。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Sid": "InvokeModel1",
"Action": [
"bedrock:InvokeModel"
],
"Resource": [
"arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-sonnet-4-20250514-v1:0",
+ "arn:aws:bedrock:ap-northeast-2::foundation-model/anthropic.claude-sonnet-4-20250514-v1:0",
+ "arn:aws:bedrock:ap-northeast-3::foundation-model/anthropic.claude-sonnet-4-20250514-v1:0",
+ (省略、合計8リージョン分指定)
"arn:aws:bedrock:ap-northeast-1:<アカウントID>:inference-profile/apac.anthropic.claude-sonnet-4-20250514-v1:0"
]
}
]
}
ただ、アジアパシフィックにおけるClaude Sonnet 4のクロスリージョン推論対応リージョンは東京含めて8つあります。
面倒くさい場合は以下のようにすれば大丈夫です。
ap-*
としておけば、アジアパシフィック全リージョンのSonnet 4に対してアクセス許可を設定できます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Sid": "InvokeModel1",
"Action": [
"bedrock:InvokeModel"
],
"Resource": [
- "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-sonnet-4-20250514-v1:0",
+ "arn:aws:bedrock:ap-*::foundation-model/anthropic.claude-sonnet-4-20250514-v1:0",
"arn:aws:bedrock:ap-northeast-1:<アカウントID>:inference-profile/apac.anthropic.claude-sonnet-4-20250514-v1:0"
]
}
]
}
いざ実行!
コンソール上から実行してみましょう。「実行を開始」ボタンから、以下のJSONを入力します。
{
"prompt": "こんにちは"
}
以下の感じの回答が返ってくるはずです。
"model": "claude-sonnet-4-20250514",
"content": [
{
"type": "text",
"text": "こんにちは!お元気ですか?何かお手伝いできることがあれば、お気軽にお声かけください。"
}
]
なぜクロスリージョン推論はSFnから利用可能なのか?
前述の通り、SFnはリージョン跨ぎのリソースアクセスはできません。
にも関わらず、なぜクロスリージョン推論が可能なのでしょうか。
呼び出している推論プロファイルが東京リージョンにあるためだと私は推測しています。
推論プロファイル(Inference Profile)とは、特定のモデルごとに使用可能なリージョンを定義したものです。
推論プロファイルのIDとしては、apac.anthropic.claude-sonnet-4-20250514-v1:0
や us.anthropic.claude-sonnet-4-20250514-v1:0
など、
<地域名>.<モデルプロバイダ名>.<モデル名>
といった形で表現されます。
Sonnet 4のクロスリージョン推論はアジアパシフィックだと8つのリージョンに対応していると書きましたが、それは推論プロファイルで予め定義されているためです。
この推論プロファイルを指定してAPIリクエストを送信するリージョン(ソースリージョンと言います)が、ここでは東京です。
SFnを東京リージョンで作成し、そのワークフロー内でAPIリクエストを送信しているためですね。
このソースリージョンが東京リージョンのため、問題なく実行できるのかなと考えています。
SFnから見ると、以下のイメージでしょうか。
- 推論プロファイル用のエンドポイントが東京にあり、そこにリクエストを送信する
- 東京リージョンの推論プロファイル用エンドポイントから回答が返ってくる
つまり、東京リージョンのBedrock基盤モデルとやり取りしている(ように、SFn視点では見えている)のではないかと。
しかし、実際のところは以下のイメージです。
- 推論プロファイル用のエンドポイントが東京にあり、そこにリクエストを送信する(同じ)
- エンドポイントの裏側で、トラフィックが混雑していないどこかのリージョンへ、リクエストが適切に送信される
- 振り分けられたリージョンのBedrock基盤モデルへリクエストをコールし、レスポンスを得る
- エンドポイントへレスポンスが返ってくる
- 東京リージョンの推論プロファイル用エンドポイントから回答が返ってくる(同じ)
実態としてクロスリージョンなリソースアクセスが行われていますが、それはSFnの知らないところで行われている、な感じなのかなと。
間違ってたらご指摘ください!
まとめ
Step Functionsでもクロスリージョン推論な基盤モデルを使用可能です!
ワークフローの中にBedrockを組み込む際は、ぜひご一考してみてはいかがでしょうか?