はじめに
GenU (Generative AI Use Cases) を利用しているときに、様々な理由で別の AWS アカウントの Amazon Bedrock を利用したいときがあります。GenU には、別の AWS アカウントを呼び出す仕組みがあり、こちらの Document でも説明されています。
ポイントを説明すると、GenU 本体が稼働している AWS アカウント「App」から、別の AWS アカウント「GenRun」にある IAM Role を利用して、別の AWS アカウントの Bedrock を呼び出せます。
元々 App で GenU を利用している前提を想定しており、Knowledge Bases を利用している場合は、S3 上のデータ移行も必要となります。
これらをどのように設定すればいいか具体的なところがわからなかったので、検証した手順を紹介します。
合わせて、クラメソさんのブログもとてもわかりやすいので、以下のブログもご参照ください。
- Generative AI Use Cases (GenU) で別 AWS アカウントの Bedrock を使ってみた
- Generative AI Use Cases (GenU) で別 AWS アカウントの Bedrock Knowledge Bases / Bedrock Agents を使ってみた
注意点
GenU で以下の機能を利用している場合、クロスアカウントの接続は一定のハードルがあります。
- MCP チャット : クロスアカウントでは利用できない。現在の実装では、crossAccountBedrockRoleArn を Assume Role はしていないのでエラーになる。今後、裏側の実装が AgentsCore に置き換わる可能性も踏まえて様子をみていくのがよいでしょう。どうしても MCP Chat を利用したい場合は、Issue を書き込むとよいです。
- Agent チャット : 利用はできるが、「GenRun」アカウントで Agent を実装する必要がある。これまでの「App」アカウントで動かしてきた Agent を移行する作業となる。Lambda 関数などを実装している場合は、それも移行が必要。GenU に組み込まれている WebSearchAgent を利用してきた場合は、手動で移行するのはなかなか大変なので、「GenRun」アカウントで実際には利用しない GenU を構築して、その中に含まれている WebSearchAgent を利用することが考える。比較的に複雑なのが玉に瑕。
Knowledge Bases
GenU を動かしている AWS アカウントを「App」と記載し、Bedrock を利用する AWS アカウントを「GenRun」と記載します。
GenRun : Model の有効化
必要なモデルの有効化をします。
GenRun : Knowledge Bases の作成
App 側で Knowledge Bases を利用している場合、GenRun 側の Bedrock を利用する際に、Knowledge Bases も GenRun 側に作成する必要があります。
まず、Knowledge Bases で利用する S3 Bucket を作成します。
S3 のレプリケーションのため Versioning を有効化するために、Properties を開きます。
Bucket Versioning を Enable にします。
Knowledge Bases を作成していきます。
S3 を data source として指定します。
前の手順で作成した S3 Bucket を選択します。余談ですが、もともとの App アカウントで利用していた S3 を利用する場合、「Other AWS account」から指定できそうです。
手動で作成した S3 バケットを選択して Choose を押します。
Next を押します。Parsing strategy などは状況に合わせて変更してください。
Embedding の設定をします。環境に合わせて変更してください。
Create
作成されました。Knowledge Base ID は後の手順で必要となるので控えます。
K2B6PZDWFG
App : S3 レプリケーションのための IAM Role 作成
App から GenRun へ S3 バケット上のデータを移行するために利用する IAM Role を作成します。これは App 側で作成します。
AmazonS3FullAccess を付与します。
Create Role をします。
作成した IAM Role の ARN をメモっておきます。
arn:aws:iam::xxxxxxxxxxxx:role/s3-replication-role
作成した IAM Role の Trust relationships を Edit します。
以下のように batchoperations
を追加します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"s3.amazonaws.com",
"batchoperations.s3.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
GenRun : S3 Bucket Policy の設定
S3 データ移行先である GenRun 側の S3 バケットで、バケットポリシーを指定します。こちらのドキュメントを参考にしました。
これが指定するバケットポリシーの書式です。
{
"Version":"2012-10-17",
"Id":"",
"Statement":[
{
"Sid":"Set-permissions-for-objects",
"Effect":"Allow",
"Principal":{
"AWS":"arn:aws:iam::source-bucket-account-ID:role/service-role/source-account-IAM-role"
},
"Action":["s3:ReplicateObject", "s3:ReplicateDelete"],
"Resource":"arn:aws:s3:::amzn-s3-demo-destination-bucket/*"
},
{
"Sid":"Set permissions on bucket",
"Effect":"Allow",
"Principal":{
"AWS":"arn:aws:iam::source-bucket-account-ID:role/service-role/source-account-IAM-role"
},
"Action":["s3:GetBucketVersioning", "s3:PutBucketVersioning"],
"Resource":"arn:aws:s3:::amzn-s3-demo-destination-bucket"
}
]
}
私の記事では、こんな感じに指定します。xxxxxxxxxxxx は AWS Account ID です。
{
"Version":"2012-10-17",
"Id":"",
"Statement":[
{
"Sid":"Set-permissions-for-objects",
"Effect":"Allow",
"Principal":{
"AWS":"arn:aws:iam::xxxxxxxxxxxx:role/s3-replication-role"
},
"Action":["s3:ReplicateObject", "s3:ReplicateDelete"],
"Resource":"arn:aws:s3:::manual-kb-lyd9q/*"
},
{
"Sid":"Set permissions on bucket",
"Effect":"Allow",
"Principal":{
"AWS":"arn:aws:iam::xxxxxxxxxxxx:role/s3-replication-role"
},
"Action":["s3:GetBucketVersioning", "s3:PutBucketVersioning"],
"Resource":"arn:aws:s3:::manual-kb-lyd9q"
}
]
}
App : S3 内のデータを移行
では、もともと利用していた S3 のデータを、GenRun 側へ移行します。
Versioning が必要なので、Enable を押します。
以下のように指定します。バケット名などは環境に合わせて書き換えてください。
Replication rule name : oneshot-object-migration
GenRun 側の S3 バケット名 : manual-kb-lyd9q
既存のオブジェクトも移行します。
作成した IAM Role を指定します。
作成されました。
一定時間後、succeeded が増えています。
サンプルデータが、GenRun 側の S3 バケットにレプリケーションされている様子が確認できました。
Gen Run : Knowledge Base で Sync
GenRun 側の Knowledge Bases で Sync をします。
Sync します。
Bedrock 用IAM Role
GenU のクロスアカウント用の IAM Role を作成します。
App : 事前調査 : IAM Role
まず、事前調査として、App 側で GenU のなかで利用している IAM Role を確認します。以下の書式のように、9 個の IAM Role の ARN が必要です。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIPredictTitleServiceXXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIPredictServiceXXXXXXXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIPredictStreamServiceXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIGenerateImageServiceXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIGenerateVideoServiceXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIListVideoJobsServiceXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-SpeechToSpeechTaskService-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-RagKnowledgeBaseRetrieveX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIGetFileDownloadSignedU-XXXXXXXXXXXX"
]
},
"Action": "sts:AssumeRole"
}
]
}
App 側の IAM の画面で、9 個ずつそれぞれ検索すると見つかります。
ここから ARN を確認できます。
App : 事前調査 : VideoTempS3 Bucket
また、App 側の動画生成のための一時的に利用する S3 Bucket の ARN も確認します。
Resource から、Bucket の画面を開きます。
以下の ARN を控えます。
arn:aws:s3:::videotmpbucketstackus-east-1-bucket83908e77-3cxqi4pklypv
なお、余談ですが、App 側の現状の S3 Bucket Policy は以下のようになっていますが、CrossAccount の設定をいれて Deploy をすると、CrossAccount 用の IAM Role が許可される Bucket Policy が自動的に増えます。興味があれば見てみてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::videotmpbucketstackus-east-1-bucket83908e77-3cxqi4pklypv",
"arn:aws:s3:::videotmpbucketstackus-east-1-bucket83908e77-3cxqi4pklypv/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxxx:role/VideoTmpBucketStackus-eas-CustomS3AutoDeleteObjects-tyvhw3ylZPbA"
},
"Action": [
"s3:DeleteObject*",
"s3:GetBucket*",
"s3:List*",
"s3:PutBucketPolicy"
],
"Resource": [
"arn:aws:s3:::videotmpbucketstackus-east-1-bucket83908e77-3cxqi4pklypv",
"arn:aws:s3:::videotmpbucketstackus-east-1-bucket83908e77-3cxqi4pklypv/*"
]
}
]
}
GenRun : IAM Role 作成
ここまでくれは、GenRun 側の IAM Role を作成します。こちらの Document を参考にすすめます。
Trust Policy の書式はこんな感じです。GenRun 側の IAM Role が、App 側の GenU を信頼するための指定です。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIPredictTitleServiceXXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIPredictServiceXXXXXXXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIPredictStreamServiceXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIGenerateImageServiceXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIGenerateVideoServiceXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIListVideoJobsServiceXX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-SpeechToSpeechTaskService-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-RagKnowledgeBaseRetrieveX-XXXXXXXXXXXX",
"arn:aws:iam::xxxxxxxxxxxx:role/GenerativeAiUseCasesStack-APIGetFileDownloadSignedU-XXXXXXXXXXXX"
]
},
"Action": "sts:AssumeRole"
}
]
}
設定例
Policy はいったん何も指定しないで Next を押します。
名前を指定して Create を押します。
作成した IAM Role に、Inline Policy を指定します。
以下の Inline Policy を指定します。
- AllowS3PutObjectToVideoTempBucket : App 側の S3 バケットの ARN を指定します。GenRun 側の Nova Reel が、AWS アカウントをまたいで、App 側のバケットにアクセスできます。
- AllowBedrockRetrieveFromKnowledgeBase : GenRun 側の手動で作成した Knowledge Base の ID を指定します。
- AllowS3GetPresignedUrl : GenRun 側の手動で作成した S3 Bucket を指定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowBedrockInvokeModel",
"Effect": "Allow",
"Action": [
"bedrock:Invoke*",
"bedrock:Rerank",
"bedrock:GetInferenceProfile",
"bedrock:GetAsyncInvoke",
"bedrock:ListAsyncInvokes",
"bedrock:GetAgent*",
"bedrock:ListAgent*"
],
"Resource": ["*"]
},
{
"Sid": "AllowS3PutObjectToVideoTempBucket",
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": ["arn:aws:s3:::videotmpbucketstackus-east-1-bucket83908e77-3cxqi4pklypv/*"]
},
{
"Sid": "AllowBedrockRetrieveFromKnowledgeBase",
"Effect": "Allow",
"Action": ["bedrock:RetrieveAndGenerate*", "bedrock:Retrieve*"],
"Resource": [
"arn:aws:bedrock:us-east-1:yyyyyyyyyyyy:knowledge-base/K2B6PZDWFG"
]
},
{
"Sid": "AllowS3GetPresignedUrl",
"Effect": "Allow",
"Action": ["s3:GetObject*"],
"Resource": ["arn:aws:s3:::manual-kb-lyd9q/*"]
}
]
}
作成した、GenRun 側の IAM Role の ARN を控えておきます。
GenU Deploy
やっと GenU の更新の手順です。cdk.json や parameter.ts 等指定方法は各環境に合わせてください。
パラメータには以下の値を設定します。
-
crossAccountBedrockRoleArn
... 最重要の設定です。GenRun アカウントで事前に作成した IAM ロールの ARN です
Knowledge Base を利用する場合は、下記パラメーターも指定します。
-
ragKnowledgeBaseEnabled
... Knowledge Base を有効化する場合はtrue
とします -
ragKnowledgeBaseId
... GenRun アカウントに事前構築した Knowledge Base の ID です - Knowledge Base は
modelRegion
に存在する必要があります
Agent Chat ユースケースを使用する場合、下記パラメーターも指定します。
-
agents
... 以下の属性を持つ Bedrock Agent の設定のリストです -
displayName
... エージェントの表示名 -
agentId
... GenRun アカウントに事前構築したエージェントの ID -
aliasId
... GenRun アカウントに事前構築したエージェントのエイリアス ID
// cdk.json
{
"context": {
"crossAccountBedrockRoleArn": "arn:aws:iam::アカウントID:role/事前に作成したロール名",
// Knowledge Base を利用する場合のみ
"ragKnowledgeBaseEnabled": true,
"ragKnowledgeBaseId": "YOUR_KNOWLEDGE_BASE_ID",
// Bedrock エージェントを利用する場合のみ
"agents": [
{
"displayName": "YOUR AGENT NAME",
"agentId": "YOUR_AGENT_ID",
"aliasId": "YOUR_AGENT_ALIAS_ID"
}
]
}
}
私の環境ではこんな感じに指定しました。
"context": {
"env": "",
"ragEnabled": false,
"kendraIndexArn": null,
"kendraIndexLanguage": "ja",
"kendraDataSourceBucketName": null,
"kendraIndexScheduleEnabled": false,
"kendraIndexScheduleCreateCron": null,
"kendraIndexScheduleDeleteCron": null,
"ragKnowledgeBaseEnabled": true,
"ragKnowledgeBaseId": "K2B6PZDWFG",
"ragKnowledgeBaseStandbyReplicas": false,
"ragKnowledgeBaseAdvancedParsing": false,
"ragKnowledgeBaseAdvancedParsingModelId": "anthropic.claude-3-sonnet-20240229-v1:0",
"ragKnowledgeBaseBinaryVector": false,
"embeddingModelId": "amazon.titan-embed-text-v2:0",
"rerankingModelId": null,
"queryDecompositionEnabled": false,
"selfSignUpEnabled": true,
"allowedSignUpEmailDomains": null,
"samlAuthEnabled": false,
"samlCognitoDomainName": "",
"samlCognitoFederatedIdentityProviderName": "",
"hiddenUseCases": {},
"modelRegion": "us-east-1",
"modelIds": [
"us.anthropic.claude-sonnet-4-20250514-v1:0",
"us.anthropic.claude-opus-4-20250514-v1:0",
"us.anthropic.claude-3-7-sonnet-20250219-v1:0",
"us.anthropic.claude-3-5-haiku-20241022-v1:0",
"us.amazon.nova-premier-v1:0",
"us.amazon.nova-pro-v1:0",
"us.amazon.nova-lite-v1:0",
"us.amazon.nova-micro-v1:0",
"us.deepseek.r1-v1:0"
],
"imageGenerationModelIds": ["amazon.nova-canvas-v1:0"],
"videoGenerationModelIds": ["amazon.nova-reel-v1:0"],
"speechToSpeechModelIds": ["amazon.nova-sonic-v1:0"],
"endpointNames": [],
"agentEnabled": false,
"searchAgentEnabled": false,
"searchEngine": "Tavily",
"searchApiKey": "",
"agents": [],
"inlineAgents": false,
"mcpEnabled": true,
"flows": [],
"allowedIpV4AddressRanges": null,
"allowedIpV6AddressRanges": null,
"allowedCountryCodes": null,
"hostName": null,
"domainName": null,
"hostedZoneId": null,
"dashboard": false,
"anonymousUsageTracking": true,
"guardrailEnabled": false,
"crossAccountBedrockRoleArn": "arn:aws:iam::yyyyyyyyyyyy:role/genu-crossaccount-role",
"useCaseBuilderEnabled": true,
}
}
deploy
npm -w packages/cdk run -- cdk deploy --require-approval never --all
動作確認
GenU から、クロスアカウントで Bedrock を実行できています。
念のため、GenU を稼働しているアカウントでは、モデルが無効化されています。
Knowledge Base もアクセスできています。
付録 : 不要になった App 側 の Knowledge Bases
Delete
削除された。
参考 URL