別アカウントの Amazon Bedrock を Assume Role でクロスアカウント接続するには?
はじめに
こんにちは、フクナガです。
本ブログでは、別アカウントの Amazon Bedrock を呼び出し、基盤モデルの利用を行うケースを想定し、実装した内容をご紹介します。
実装する環境の概要
本ブログでは、AWS アカウント① 上に構築した AWS Lambda から、AWS アカウント② 上の Amazon Bedrock を呼び出す方法をご紹介します。
[構成図]
権限付与の部分をおさえることで、AWS Lambda 以外のリソースからも実行することが可能となります。
事前準備
本ブログでは、権限付与の部分に重きを置いてご説明しますので、登場リソースの構築を先に実施します。
① Amazon Bedrock を呼び出す AWS Lambda の構築
同一アカウントの Amazon Bedrock を呼び出す AWS Lambda の構築を実施します。
ユーザーからのメッセージに対し、Amazon Bedrock を呼び出して回答する簡易なコード例を記載します。
1. Lambda コード
import json import boto3 from botocore.exceptions import ClientError def lambda_handler(event, context): # Bedrockクライアントを作成 bedrock_runtime = boto3.client( service_name='bedrock-runtime', region_name='us-east-1' # Bedrockが利用可能なリージョンを指定 ) # リクエストから質問を取得 try: body = json.loads(event.get('body', '{}')) user_message = body.get('message', 'Hello, how are you?') except: user_message = 'Hello, how are you?' # Claude 4のモデルID model_id = "us.anthropic.claude-sonnet-4-20250514-v1:0" # リクエストボディを作成 request_body = { "anthropic_version": "bedrock-2023-05-31", "max_tokens": 1000, "messages": [ { "role": "user", "content": user_message } ] } try: # Bedrockにリクエストを送信 response = bedrock_runtime.invoke_model( modelId=model_id, contentType='application/json', accept='application/json', body=json.dumps(request_body) ) # レスポンスを解析 response_body = json.loads(response['body'].read()) generated_text = response_body['content'][0]['text'] return { 'statusCode': 200, 'headers': { 'Content-Type': 'application/json' }, 'body': json.dumps({ 'message': generated_text, 'model_used': model_id }, ensure_ascii=False) } except ClientError as e: print(f"Error calling Bedrock: {e}") return { 'statusCode': 500, 'body': json.dumps({ 'error': 'Failed to call Bedrock', 'details': str(e) }) } except Exception as e: print(f"Unexpected error: {e}") return { 'statusCode': 500, 'body': json.dumps({ 'error': 'Internal server error', 'details': str(e) }) }
2. IAM ロール
同一の Amazon Bedrock を呼び出す場合は、AWS Lambda の IAM ロールに Amazon Bedrock を利用するためのロールをアタッチすることで実現可能です。
3. タイムアウト
回答は大抵デフォルトタイムアウト値の 3 秒では実施できませんので、タイムアウト値を伸ばしておきます。
簡易な質問しかしない想定ですので、一旦 30 秒に設定しました。
② 今回利用する Amazon Bedrock 用アカウントで対象言語モデルの有効化を実施する
Amazon Bedrock コンソールの左側に表示されるメニューの「Configure and Learn」>「モデルアクセス」から現状有効化されているモデルを確認できます。
自身が利用するモデルが有効化されていない場合は、モデルアクセスをリクエストしましょう。
手順
↓ここからは、Amazon Bedrock 用アカウントで実施
1. IAM コンソールへ遷移
2. 左側メニューから「ロール」を選択し、「ロールを作成」を押下
3. 下記を選択、入力し「次へ」を押下
信頼されたエンティティタイプ:AWS アカウント
AWS アカウント:別の AWS アカウント
アカウント ID:Lambda が構築されたアカウントの ID を入力
オプション:外部 ID を要求する (サードパーティがこのロールを引き受ける場合のベストプラクティス)
外部 ID:任意の英数字の文字列を入力する
※この値は後ほど利用しますので控えておきましょう
4. 何も選択せずに「次へ」を押下
※後ほど許可ポリシーを作成します。
5. ロール名を入力し、「ロールを作成」を押下
6. 作成した IAM ロールを選択する
7. 「許可」>「許可を追加」>「インラインポリシーを作成」を押下
8. 下記をそれぞれ選択し、「次へ」を押下
サービス:Amazon Bedrock
アクション許可:InvokeModel
リソース:foundation-model、inference-profile
※利用するモデルを絞った権限付与も可能ですが、今後のモデル増加などに対応するためこちらの設定としております。
9. ポリシー名を入力し、「ポリシーの作成」を押下する
10. 「信頼関係」>「信頼ポリシーを編集」を押下
11. Principal の部分を下記のように修正し、「ポリシーを更新」を押下
"Principal": { "AWS": "[構築した Lambda の IAM Role ARN]" },
↓ここからは、AWS Lambda を構築したアカウントで実施します
12. 作成した Lambda 関数を選択し、「設定」>「アクセス権限」から IAM ロールを選択
13. IAM ロールの許可ポリシーから Amazon Bedrock へのアクセス権限を付与するポリシーを削除する
元々ポリシーをアタッチ、作成していない場合は本手順は不要です。
14. 「許可を追加」>「インラインポリシーを作成」を押下
15. 下記をそれぞれ選択し、「次へ」を押下
サービス:STS
アクション許可:AssumeRole
リソース:「特定」を選択し、Amazon Bedrock 用の IAM Role として作成したロールの ARN を入力する
16. 「ポリシー名」を入力し、「ポリシーの作成」を押下
17. 作成した Lambda 関数を選択し、コードを修正する
Assume Role をコード内で実施するようコードを修正します。
以下にコードの例を記載しますが、本番運用を考慮する場合認証情報を外だししたりなど適宜修正を加えましょう。
import json import boto3 from botocore.exceptions import ClientError TARGET_ROLE_ARN='{Assume Role する対象の IAM ロールの ARN}' EXTERNAL_ID='{Assume Role するために必要な外部 ID(手順 3 にて設定)}' def get_session(role_arn, role_session_name,external_id): sts_client = boto3.client('sts') assumed_role = sts_client.assume_role( RoleArn=role_arn, RoleSessionName=role_session_name, ExternalId=external_id ) print("Successfully assumed role") session = boto3.session.Session( aws_access_key_id=assumed_role['Credentials']['AccessKeyId'], aws_secret_access_key=assumed_role['Credentials']['SecretAccessKey'], aws_session_token=assumed_role['Credentials']['SessionToken'], ) return session def lambda_handler(event, context): session = get_session(TARGET_ROLE_ARN, 'assume-role-session',"EXTERNAL_ID") # Bedrockクライアントを作成 bedrock_runtime = session.client( service_name='bedrock-runtime', region_name='us-east-1' # Bedrockが利用可能なリージョンを指定 ) # リクエストから質問を取得 try: body = json.loads(event.get('body', '{}')) user_message = body.get('message', 'Hello, how are you?') except: user_message = 'Hello, how are you?' # Claude 4のモデルID model_id = "us.anthropic.claude-sonnet-4-20250514-v1:0" # リクエストボディを作成 request_body = { "anthropic_version": "bedrock-2023-05-31", "max_tokens": 1000, "messages": [ { "role": "user", "content": user_message } ] } try: # Bedrockにリクエストを送信 response = bedrock_runtime.invoke_model( modelId=model_id, contentType='application/json', accept='application/json', body=json.dumps(request_body) ) # レスポンスを解析 response_body = json.loads(response['body'].read()) generated_text = response_body['content'][0]['text'] return { 'statusCode': 200, 'headers': { 'Content-Type': 'application/json' }, 'body': json.dumps({ 'message': generated_text, 'model_used': model_id }, ensure_ascii=False) } except ClientError as e: print(f"Error calling Bedrock: {e}") return { 'statusCode': 500, 'body': json.dumps({ 'error': 'Failed to call Bedrock', 'details': str(e) }) } except Exception as e: print(f"Unexpected error: {e}") return { 'statusCode': 500, 'body': json.dumps({ 'error': 'Internal server error', 'details': str(e) }) }
18. 完成した Lambda 関数が実行できることを確認する
AWS Lambda コンソール上のテスト機能を利用して、実行ができるか確認しました。
テスト用 JSON の例
{ "body": "{"message": "Hello, please introduce yourself."}" }
実行した結果、問題なく処理が完了し、生成 AI から回答が返ってくることを確認できました。
Amazon Bedrock の各モデルの呼び出し状況の確認方法
構築した Lambda 関数が実行できたことを確認するだけだと、本当に別アカウント上で Amazon Bedrock を実行しているか不安な方もいらっしゃると思います。
Amazon CloudWatch 上で、Amazon Bedrock のモデルの呼び出しについて確認することができますので、そちらでも確認してみましょう!
確認方法
1. Amazon CloudWatch コンソールから「すべてのメトリクス」メニューを選択、「Bedrock」を選択
2. 「モデル ID 別」を選択
3. 対象のモデル ID に対する「Invocations」を確認する
4. 「グラフ化されたメトリクス」を選択し、「統計」を「合計」に、「期間」を「1時間」に変更する
こちらはあくまで可視化の例となりますので、見たい内容に合わせて各設定値を変更することを推奨します。
今回は、呼び出されたか否かが知りたいのでこういった設定値にしました。
① AWS Lambda が構築されたアカウントでの呼び出し状況
直近 1 時間のメトリクスを確認し、対象のモデルが呼び出されていないことを確認できました!
② Amazon Bedrock が呼び出されると想定されるアカウントでの呼び出し状況
Lambda 関数を実行した回数だけ、こちらの指標が上がっていることが確認できました。
まとめ
本ブログでは、AWS Lambda から別アカウント上で Amazon Bedrock を呼び出す方法をご紹介しました。
アカウントの利用方法は、各組織や事情によってさまざまだと思いますので、Amazon Bedrock を別アカウントでご利用したい場合は、本手順をご参考にしていただければ幸いです。
参考リンク
InvokeModel
Supported Regions and models for inference profiles
Amazon Bedrock のパフォーマンスのモニタリング
別の AWS アカウントで IAM ロールを引き受けるように Lambda 関数を設定するにはどうすればよいですか?
テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!
Follow @twitter2025 Japan AWS Ambassadors / Google Cloud Partner Top Engineer 2025 / 2024 Japan AWS Top Engineers 選出されました! 生成 AI 多めで発信していますが、CI/CDやIaCへの関心も高いです。休日はベースを弾いてます。
Recommends
こちらもおすすめ
-
営業が電子工作を始めてみた話(AWS IoTとかのお話)
2015.12.24
Special Topics
注目記事はこちら

データ分析入門
これから始めるBigQuery基礎知識
2024.02.28

AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16