🔄

GenU で別 AWS アカウントの Bedrock を利用する手順

に公開

はじめに

GenU (Generative AI Use Cases) を利用しているときに、様々な理由で別の AWS アカウントの Amazon Bedrock を利用したいときがあります。GenU には、別の AWS アカウントを呼び出す仕組みがあり、こちらの Document でも説明されています。

image-20250720133805616

ポイントを説明すると、GenU 本体が稼働している AWS アカウント「App」から、別の AWS アカウント「GenRun」にある IAM Role を利用して、別の AWS アカウントの Bedrock を呼び出せます。

元々 App で GenU を利用している前提を想定しており、Knowledge Bases を利用している場合は、S3 上のデータ移行も必要となります。

これらをどのように設定すればいいか具体的なところがわからなかったので、検証した手順を紹介します。

合わせて、クラメソさんのブログもとてもわかりやすいので、以下のブログもご参照ください。

注意点

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 の有効化

必要なモデルの有効化をします。

image-20250720133537902

GenRun : Knowledge Bases の作成

App 側で Knowledge Bases を利用している場合、GenRun 側の Bedrock を利用する際に、Knowledge Bases も GenRun 側に作成する必要があります。

まず、Knowledge Bases で利用する S3 Bucket を作成します。

image-20250720015215625

S3 のレプリケーションのため Versioning を有効化するために、Properties を開きます。

image-20250720023821836

Bucket Versioning を Enable にします。

image-20250720023846425

Knowledge Bases を作成していきます。

image-20250720014640852

S3 を data source として指定します。

image-20250720014745812

前の手順で作成した S3 Bucket を選択します。余談ですが、もともとの App アカウントで利用していた S3 を利用する場合、「Other AWS account」から指定できそうです。

image-20250720015440099

手動で作成した S3 バケットを選択して Choose を押します。

image-20250720015500945

Next を押します。Parsing strategy などは状況に合わせて変更してください。

image-20250720015536056

Embedding の設定をします。環境に合わせて変更してください。

image-20250720015648496

Create

image-20250720015732100

作成されました。Knowledge Base ID は後の手順で必要となるので控えます。

K2B6PZDWFG

image-20250720015935318

App : S3 レプリケーションのための IAM Role 作成

App から GenRun へ S3 バケット上のデータを移行するために利用する IAM Role を作成します。これは App 側で作成します。

image-20250720025725907

AmazonS3FullAccess を付与します。

image-20250720024749031

Create Role をします。

image-20250720025802890

作成した IAM Role の ARN をメモっておきます。

arn:aws:iam::xxxxxxxxxxxx:role/s3-replication-role

作成した IAM Role の Trust relationships を Edit します。

image-20250720030743726

以下のように 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 バケットで、バケットポリシーを指定します。こちらのドキュメントを参考にしました。

image-20250720025936442

これが指定するバケットポリシーの書式です。

{
   "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 側へ移行します。

image-20250720023321222

Versioning が必要なので、Enable を押します。

image-20250720023339952

以下のように指定します。バケット名などは環境に合わせて書き換えてください。

Replication rule name : oneshot-object-migration

GenRun 側の S3 バケット名 : manual-kb-lyd9q

image-20250720030553011

既存のオブジェクトも移行します。

image-20250720024123666

作成した IAM Role を指定します。

image-20250720030642408

作成されました。

image-20250720024208622

一定時間後、succeeded が増えています。

image-20250720031404546

サンプルデータが、GenRun 側の S3 バケットにレプリケーションされている様子が確認できました。

image-20250720031503225

Gen Run : Knowledge Base で Sync

GenRun 側の Knowledge Bases で Sync をします。

image-20250720101451053

Sync します。

image-20250720101535321

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 個ずつそれぞれ検索すると見つかります。

image-20250720110255100

ここから ARN を確認できます。

image-20250720135230886

App : 事前調査 : VideoTempS3 Bucket

また、App 側の動画生成のための一時的に利用する S3 Bucket の ARN も確認します。

image-20250720110346316

Resource から、Bucket の画面を開きます。

image-20250720110509694

以下の ARN を控えます。

arn:aws:s3:::videotmpbucketstackus-east-1-bucket83908e77-3cxqi4pklypv

image-20250720110756563

なお、余談ですが、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 を参考にすすめます。

image-20250720101845310

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"
    }
  ]
}

設定例

image-20250720111113655

Policy はいったん何も指定しないで Next を押します。

image-20250720111134380

名前を指定して Create を押します。

image-20250720111157721

作成した IAM Role に、Inline Policy を指定します。

image-20250720111305864

以下の 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/*"]
    }
  ]
}

image-20250720111824101

作成した、GenRun 側の IAM Role の ARN を控えておきます。

image-20250720140053440

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 を実行できています。

image-20250720140441430

念のため、GenU を稼働しているアカウントでは、モデルが無効化されています。

image-20250720140603855

Knowledge Base もアクセスできています。

image-20250720140738392

付録 : 不要になった App 側 の Knowledge Bases

image-20250720132218769

Delete

image-20250720132235933

削除された。

image-20250720132459566

参考 URL

https://aws-samples.github.io/generative-ai-use-cases/ja/DEPLOY_OPTION.html#別-aws-アカウントの-bedrock-を利用したい場合

https://dev.classmethod.jp/articles/genu-bedrock-crossaccount/

https://dev.classmethod.jp/articles/genu-bedrock-knowledgebases-agents-crossaccount/

アマゾン ウェブ サービス ジャパン (有志)

Discussion