はじめに
Claude CodeのバックエンドにAmazon Bedrockを使っていると、こんな構成にしたくなることがあります。
- Claude Codeから実行する
awsコマンドは「開発用AWSアカウント」に向けたい - Claude CodeのAmazon Bedrock利用料は「生成AI用AWSアカウント」に集約したい
今回作る構成はこちらです。
Claude Code
│
┌───────────┴───────────┐
│ │
Bash Tool Claudeの推論
│ │
aws CLI awsCredentialExport
│ │
▼ ▼
操作用アカウント Bedrock用アカウント
Account-A Account-B
ポイントは、Claude Codeの awsCredentialExport を使って、AWS CLIの操作対象アカウントに対する認証と、Bedrock用アカウントに対する認証を分けることです。
Claude Code公式ドキュメントの「Advanced credential configuration」でも、awsCredentialExport は、通常のAWS認証チェーンとは異なるクロスアカウント認証情報をAmazon Bedrockで使う場合の設定として説明されています。
今回は実際に2つのAWS profileを用意し、
work → Account-A
bedrock → Account-B
として動作確認します。
前提
この記事では以下の名前を使います。
| 用途 | AWSアカウント | AWS CLI profile |
|---|---|---|
| AWSリソース操作 | Account-A | work |
| Amazon Bedrock | Account-B | bedrock |
Account-Bでは、us-east-1 でAnthropic Claudeを呼び出せる状態にしておきます。今回はAmazon BedrockのPlaygroundで応答が返ることを事前に確認しました。
事前にAWS CLI v2とClaude Codeをインストールし、次のコマンドを実行できることを確認します。
aws --version
claude --version
検証環境は次のとおりです。
| ツール | バージョン |
|---|---|
| AWS CLI | 2.36.25 |
| Claude Code | 2.1.227 |
この記事では、Claude Code v2.1.181以降を使用します。Claude Code公式CHANGELOGのv2.1.181に記載されているとおり、このバージョンから aws configure export-credentials --format process が返すJSONを awsCredentialExport で直接利用できるようになりました。
以前のバージョンでは、JSON形式を変換する処理が必要でした。
1. 2つのAWS profileを準備する
IAM Identity Centerを利用して、Account-A用の work profileを作成します。
aws configure sso --profile work
同様に、Account-B用の bedrock profileを作成します。
aws configure sso --profile bedrock
work profileでSSOログインし、接続先を確認します。
aws sso login --profile work
aws sts get-caller-identity --profile work
続いて、bedrock profileでも同じ順番で確認します。
aws sso login --profile bedrock
aws sts get-caller-identity --profile bedrock
実際の確認結果は次のとおりでした。Account ID、ロール識別子、セッション名は公開用にマスクしています。
work / Account-A
{
"UserId": "AROAYS2N************:****",
"Account": "5901****3868",
"Arn": "arn:aws:sts::5901****3868:assumed-role/AWSReservedSSO_AWSAdministratorAccess_****/****"
}
bedrock / Account-B
{
"UserId": "AROARRP5************:****",
"Account": "1062****9598",
"Arn": "arn:aws:sts::1062****9598:assumed-role/AWSReservedSSO_AWSAdministratorAccess_****/****"
}
work と bedrock で異なるAccount IDが返っているため、2つのprofileが別々のAWSアカウントを参照していることを確認できました。
2. export-credentials の動作を確認する
bedrock profileの一時認証情報を、Claude Codeが利用できる形式で出力できることを確認します。
aws configure export-credentials \
--profile bedrock \
--format process
一時認証情報を使用している場合は、概ね以下のようなJSONが返ります。
{
"Version": 1,
"AccessKeyId": "ASIA...",
"SecretAccessKey": "...",
"SessionToken": "...",
"Expiration": "..."
}
Claude Code v2.1.181以降では、このJSON形式を awsCredentialExport が直接受け取れます。
3. Claude CodeにBedrockを設定する
Claude Codeの設定ファイルを編集します。
~/.claude/settings.json
以下を設定します。
{
"env": {
"CLAUDE_CODE_USE_BEDROCK": "1",
"AWS_REGION": "us-east-1"
},
"awsCredentialExport": "aws configure export-credentials --profile bedrock --format process"
}
CLAUDE_CODE_USE_BEDROCK でAmazon Bedrockを有効にし、AWS_REGION で利用リージョンを指定します。awsCredentialExport はBedrock用の認証情報が必要になったときに実行され、bedrock profileの一時認証情報をClaude Codeへ渡します。
4. AWS CLIの操作先をAccount-Aにする
Claude Codeを起動するターミナルでは、通常のAWS CLIが work profileを使うように設定します。
export AWS_PROFILE=work
確認します。
aws sts get-caller-identity
確認結果としてAccount-Aが返れば準備完了です。
5. Claude Codeを起動する
claude --model haiku
今回は接続確認が目的のため、推論コストを抑えられるHaikuを指定しています。
Claude Code内で、
/status
を実行して、Amazon Bedrockを利用していることを確認します。
今回の環境では、次の内容を確認できました。
API provider: Amazon Bedrock
AWS region: us-east-1
Model: haiku
これにより、Claude Code自身の推論がAmazon Bedrockを利用していることが分かります。
6. Claude CodeからAWS CLIを実行してみる
Claude Codeに次のように依頼します。
aws sts get-caller-identity を実行して、現在操作しているAWSアカウントを確認してください。
Claude CodeがBash Toolから実行します。
aws sts get-caller-identity
実行結果ではAccount-A(5901****3868)が返りました。これにより、Claude Code内で実行されるAWS CLIが work profileを利用していることを確認できました。
構成の最終形
Claude Code
│
┌──────────┴──────────┐
│ │
Bash Bedrock
│ │
aws CLI awsCredentialExport
│ │
profile=work profile=bedrock
│ │
▼ ▼
Account-A Account-B
AWS_PROFILE=bedrock だけではだめなのか
次の方法でも、Claude CodeはAccount-BのBedrockを利用できます。
export AWS_PROFILE=bedrock
export CLAUDE_CODE_USE_BEDROCK=1
claude
ただし、AWS_PROFILE はBash Toolにも引き継がれるため、Claude Code内で実行するAWS CLIまでAccount-Bを向いてしまいます。
Claude Codeの推論 → Account-B
Claude Code内のAWS CLI → Account-B
今回必要なのは次の構成です。
Claude Code内のAWS CLI → Account-A
Claude Codeの推論 → Account-B
そのため、通常のAWS CLIには work を指定し、Bedrock認証だけを awsCredentialExport で bedrock に分けます。
export AWS_PROFILE=work
claude
なお、Claude Code内の aws sts get-caller-identity が示すのはBash Toolの接続先です。Account-Aが返っても、Bedrockの認証先がAccount-Aという意味ではありません。
2つのprofileを比較する
この動作を確認するため、次のスクリプトを使用しました。claude -p はClaude Codeを非対話モードで実行し、処理が終わると結果を表示して終了します。
#!/usr/bin/env bash
set -euo pipefail
for profile in work bedrock; do
echo
echo "=== AWS_PROFILE=${profile} ==="
AWS_PROFILE="${profile}" \
CLAUDE_CODE_USE_BEDROCK=1 \
AWS_REGION=us-east-1 \
claude -p \
"aws sts get-caller-identity を実行し、結果だけ表示してください" \
--model haiku \
--allowedTools "Bash(aws sts get-caller-identity*)"
done
実行します。
./compare-aws-accounts.sh
実行結果は次のとおりです。Account ID、ロール識別子、セッション名はマスクしています。
=== AWS_PROFILE=work ===
{
"UserId": "AROAYS2N************:****",
"Account": "5901****3868",
"Arn": "arn:aws:sts::5901****3868:assumed-role/AWSReservedSSO_AWSAdministratorAccess_****/****"
}
=== AWS_PROFILE=bedrock ===
{
"UserId": "AROARRP5************:****",
"Account": "1062****9598",
"Arn": "arn:aws:sts::1062****9598:assumed-role/AWSReservedSSO_AWSAdministratorAccess_****/****"
}
AWS_PROFILE に応じて、Claude Code内のAWS CLI操作先がAccount-AとAccount-Bへ切り替わることを確認できました。
まとめ
今回の構成では、2つの接続先を次のように分離できました。
- AWS CLI操作先 → Account-A
- Bedrock課金先 → Account-B
ポイントは次の4点です。
-
awsCredentialExportでBedrock認証だけ分離 - AWS CLIは通常の
AWS_PROFILEを利用 - Claude Code内のSTS結果はBash Toolの接続先を示す
- Claude Code v2.1.181以降でシンプルに構成可能