Skip to content

Commit 2a09fb7

Browse files
authored
Add support for cross-account agents (#1053)
1 parent d628553 commit 2a09fb7

File tree

5 files changed

+114
-25
lines changed

5 files changed

+114
-25
lines changed

docs/en/DEPLOY_OPTION.md

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,7 +1768,7 @@ const envs: Record<string, Partial<StackInput>> = {
17681768
## Using Bedrock from a Different AWS Account
17691769

17701770
> [!NOTE]
1771-
> Agent-related tasks (Agent, Flow, Prompt Optimization Tool) do not support using a different AWS account and may result in errors during execution.
1771+
> Flow Chat use case and Prompt Optimization Tool do not support using a different AWS account and may result in errors during execution.
17721772
17731773
You can use Bedrock from a different AWS account. As a prerequisite, the initial deployment of GenU must be completed.
17741774

@@ -1827,11 +1827,13 @@ For details on how to specify Principals, refer to: [AWS JSON Policy Elements: P
18271827
"Sid": "AllowBedrockInvokeModel",
18281828
"Effect": "Allow",
18291829
"Action": [
1830-
"bedrock:InvokeModel*",
1830+
"bedrock:Invoke*",
18311831
"bedrock:Rerank",
18321832
"bedrock:GetInferenceProfile",
18331833
"bedrock:GetAsyncInvoke",
1834-
"bedrock:ListAsyncInvokes"
1834+
"bedrock:ListAsyncInvokes",
1835+
"bedrock:GetAgent*",
1836+
"bedrock:ListAgent*"
18351837
],
18361838
"Resource": ["*"]
18371839
},
@@ -1871,6 +1873,13 @@ When using Knowledge Base, you'll need to include these additional parameters:
18711873
- `ragKnowledgeBaseId` ... Knowledge Base ID created in advance in the different account
18721874
- Knowledge Base must exist in the `modelRegion`
18731875

1876+
When using Agent Chat use case, you'll need to include these additional parameters:
1877+
1878+
- `agents` ... a list of Bedrock Agent configurations, which has following properties:
1879+
- `displayName` ... Display name of the agent
1880+
- `agentId` ... Agent ID created in advance in the different account
1881+
- `aliasId` ... Agent Alias ID created in advance in the different account
1882+
18741883
**Edit [parameter.ts](/packages/cdk/parameter.ts)**
18751884

18761885
```typescript
@@ -1879,8 +1888,17 @@ const envs: Record<string, Partial<StackInput>> = {
18791888
dev: {
18801889
crossAccountBedrockRoleArn:
18811890
'arn:aws:iam::AccountID:role/PreCreatedRoleName',
1882-
ragKnowledgeBaseEnabled: true, // Only when using Knowledge Base
1883-
ragKnowledgeBaseId: 'XXXXXXXXXX', // Only when using Knowledge Base
1891+
// Only when using Knowledge Base
1892+
ragKnowledgeBaseEnabled: true,
1893+
ragKnowledgeBaseId: 'YOUR_KNOWLEDGE_BASE_ID',
1894+
// Only when using agents
1895+
agents: [
1896+
{
1897+
displayName: 'YOUR AGENT NAME',
1898+
agentId: 'YOUR_AGENT_ID',
1899+
aliasId: 'YOUR_AGENT_ALIAS_ID',
1900+
},
1901+
],
18841902
},
18851903
};
18861904
```
@@ -1892,8 +1910,17 @@ const envs: Record<string, Partial<StackInput>> = {
18921910
{
18931911
"context": {
18941912
"crossAccountBedrockRoleArn": "arn:aws:iam::AccountID:role/PreCreatedRoleName",
1895-
"ragKnowledgeBaseEnabled": true, // Only when using Knowledge Base
1896-
"ragKnowledgeBaseId": "XXXXXXXXXX" // Only when using Knowledge Base
1913+
// Only when using Knowledge Base
1914+
"ragKnowledgeBaseEnabled": true,
1915+
"ragKnowledgeBaseId": "YOUR_KNOWLEDGE_BASE_ID",
1916+
// Only when using agents
1917+
"agents": [
1918+
{
1919+
"displayName": "YOUR AGENT NAME",
1920+
"agentId": "YOUR_AGENT_ID",
1921+
"aliasId": "YOUR_AGENT_ALIAS_ID"
1922+
}
1923+
]
18971924
}
18981925
}
18991926
```

docs/ja/DEPLOY_OPTION.md

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,7 +1775,7 @@ const envs: Record<string, Partial<StackInput>> = {
17751775
## 別 AWS アカウントの Bedrock を利用したい場合
17761776

17771777
> [!NOTE]
1778-
> Agent 系のタスク (Agent, Flow, プロンプト最適化ツール) に関しては別 AWS アカウントの利用をサポートしていないため、実行時にエラーになる可能性があります。
1778+
> Flow チャットユースケース」および「プロンプト最適化ツール」は別 AWS アカウントの利用をサポートしていないため、実行時にエラーになる可能性があります。
17791779
17801780
別 AWS アカウントの Bedrock を利用することができます。前提条件として、GenU の初回デプロイは完了済みとします。
17811781

@@ -1834,11 +1834,13 @@ Principal の指定方法について詳細を確認したい場合はこちら
18341834
"Sid": "AllowBedrockInvokeModel",
18351835
"Effect": "Allow",
18361836
"Action": [
1837-
"bedrock:InvokeModel*",
1837+
"bedrock:Invoke*",
18381838
"bedrock:Rerank",
18391839
"bedrock:GetInferenceProfile",
18401840
"bedrock:GetAsyncInvoke",
1841-
"bedrock:ListAsyncInvokes"
1841+
"bedrock:ListAsyncInvokes",
1842+
"bedrock:GetAgent*",
1843+
"bedrock:ListAgent*"
18421844
],
18431845
"Resource": ["*"]
18441846
},
@@ -1878,6 +1880,13 @@ Knowledge Base を利用する場合は、下記パラメーターも指定し
18781880
- `ragKnowledgeBaseId` ... 別アカウントに事前構築した Knowledge Base の ID です
18791881
- Knowledge Base は `modelRegion` に存在する必要があります
18801882

1883+
Agent Chat ユースケースを使用する場合、下記パラメーターも指定します。
1884+
1885+
- `agents` ... 以下の属性を持つ Bedrock Agent の設定のリストです
1886+
- `displayName` ... エージェントの表示名
1887+
- `agentId` ... 別アカウントに事前構築したエージェントの ID
1888+
- `aliasId` ... 別アカウントに事前構築したエージェントのエイリアス ID
1889+
18811890
**[parameter.ts](/packages/cdk/parameter.ts) を編集**
18821891

18831892
```typescript
@@ -1886,8 +1895,17 @@ const envs: Record<string, Partial<StackInput>> = {
18861895
dev: {
18871896
crossAccountBedrockRoleArn:
18881897
'arn:aws:iam::アカウントID:role/事前に作成したロール名',
1889-
ragKnowledgeBaseEnabled: true, // Knowledge Base を利用する場合のみ
1890-
ragKnowledgeBaseId: 'XXXXXXXXXX', // Knowledge Base を利用する場合のみ
1898+
// Knowledge Base を利用する場合のみ
1899+
ragKnowledgeBaseEnabled: true,
1900+
ragKnowledgeBaseId: 'YOUR_KNOWLEDGE_BASE_ID',
1901+
// Bedrock エージェントを利用する場合のみ
1902+
agents: [
1903+
{
1904+
displayName: 'YOUR AGENT NAME',
1905+
agentId: 'YOUR_AGENT_ID',
1906+
aliasId: 'YOUR_AGENT_ALIAS_ID',
1907+
},
1908+
],
18911909
},
18921910
};
18931911
```
@@ -1899,8 +1917,17 @@ const envs: Record<string, Partial<StackInput>> = {
18991917
{
19001918
"context": {
19011919
"crossAccountBedrockRoleArn": "arn:aws:iam::アカウントID:role/事前に作成したロール名",
1902-
"ragKnowledgeBaseEnabled": true, // Knowledge Base を利用する場合のみ
1903-
"ragKnowledgeBaseId": "XXXXXXXXXX" // Knowledge Base を利用する場合のみ
1920+
// Knowledge Base を利用する場合のみ
1921+
"ragKnowledgeBaseEnabled": true,
1922+
"ragKnowledgeBaseId": "YOUR_KNOWLEDGE_BASE_ID",
1923+
// Bedrock エージェントを利用する場合のみ
1924+
"agents": [
1925+
{
1926+
"displayName": "YOUR AGENT NAME",
1927+
"agentId": "YOUR_AGENT_ID",
1928+
"aliasId": "YOUR_AGENT_ALIAS_ID"
1929+
}
1930+
]
19041931
}
19051932
}
19061933
```

packages/cdk/lambda/utils/bedrockAgentApi.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import {
2-
BedrockAgentClient,
32
GetAgentAliasCommand,
43
ListAgentActionGroupsCommand,
54
} from '@aws-sdk/client-bedrock-agent';
65
import {
7-
BedrockAgentRuntimeClient,
86
DependencyFailedException,
97
InvokeAgentCommand,
108
Parameter,
@@ -22,13 +20,12 @@ import {
2220
BraveSearchResult,
2321
} from 'generative-ai-use-cases';
2422
import { streamingChunk } from './streamingChunk';
23+
import {
24+
initBedrockAgentClient,
25+
initBedrockAgentRuntimeClient,
26+
} from './bedrockClient';
2527

26-
const agentClient = new BedrockAgentClient({
27-
region: process.env.MODEL_REGION,
28-
});
29-
const agentRuntimeClient = new BedrockAgentRuntimeClient({
30-
region: process.env.MODEL_REGION,
31-
});
28+
const MODEL_REGION = process.env.MODEL_REGION as string;
3229
const s3Client = new S3Client({});
3330

3431
// Agent information
@@ -64,8 +61,11 @@ const encodeUrlString = (str: string): string => {
6461
const getAgentInfo = async (agentId: string, agentAliasId: string) => {
6562
// Get Agent Info if not cached
6663
if (!agentInfoMap[agentAliasId]) {
64+
const bedrockAgentClient = await initBedrockAgentClient({
65+
region: MODEL_REGION,
66+
});
6767
// Get Agent Version
68-
const agentAliasInfoRes = await agentClient.send(
68+
const agentAliasInfoRes = await bedrockAgentClient.send(
6969
new GetAgentAliasCommand({
7070
agentId: agentId,
7171
agentAliasId: agentAliasId,
@@ -75,7 +75,7 @@ const getAgentInfo = async (agentId: string, agentAliasId: string) => {
7575
agentAliasInfoRes.agentAlias?.routingConfiguration?.pop()?.agentVersion ??
7676
'1';
7777
// List Action Group
78-
const actionGroups = await agentClient.send(
78+
const actionGroups = await bedrockAgentClient.send(
7979
new ListAgentActionGroupsCommand({
8080
agentId: agentId,
8181
agentVersion: agentVersion,
@@ -129,7 +129,11 @@ const bedrockAgentApi: ApiInterface = {
129129
enableTrace: true,
130130
inputText: messages[messages.length - 1].content,
131131
});
132-
const res = await agentRuntimeClient.send(command);
132+
133+
const bedrockAgentRuntimeClient = await initBedrockAgentRuntimeClient({
134+
region: MODEL_REGION,
135+
});
136+
const res = await bedrockAgentRuntimeClient.send(command);
133137

134138
if (!res.completion) {
135139
return;

packages/cdk/lambda/utils/bedrockClient.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@ import {
88
BedrockAgentRuntimeClientConfig,
99
} from '@aws-sdk/client-bedrock-agent-runtime';
1010
import { S3Client, S3ClientConfig } from '@aws-sdk/client-s3';
11+
import {
12+
BedrockAgentClient,
13+
BedrockAgentClientConfig,
14+
} from '@aws-sdk/client-bedrock-agent';
1115

1216
// Temporary credentials for cross-account access
1317
const stsClient = new STSClient();
1418
let temporaryCredentials: Credentials | undefined;
1519

1620
// Store Bedrock clients
1721
let bedrockRuntimeClient: BedrockRuntimeClient | undefined;
22+
let bedrockAgentClient: BedrockAgentClient | undefined;
1823
let bedrockAgentRuntimeClient: BedrockAgentRuntimeClient | undefined;
1924
let knowledgeBaseS3Client: S3Client | undefined;
2025

@@ -91,6 +96,25 @@ export const initBedrockRuntimeClient = async (
9196
return bedrockRuntimeClient;
9297
};
9398

99+
export const initBedrockAgentClient = async (
100+
config: BedrockAgentClientConfig & { region: string }
101+
) => {
102+
// Use cross-account role
103+
if (process.env.CROSS_ACCOUNT_BEDROCK_ROLE_ARN) {
104+
return new BedrockAgentClient({
105+
...(await getCrossAccountCredentials(
106+
process.env.CROSS_ACCOUNT_BEDROCK_ROLE_ARN
107+
)),
108+
...config,
109+
});
110+
}
111+
// Use Lambda execution role
112+
if (!bedrockAgentClient) {
113+
bedrockAgentClient = new BedrockAgentClient(config);
114+
}
115+
return bedrockAgentClient;
116+
};
117+
94118
export const initBedrockAgentRuntimeClient = async (
95119
config: BedrockAgentRuntimeClientConfig & { region: string }
96120
) => {

packages/cdk/lib/create-stacks.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ export const createStacks = (app: cdk.App, params: ProcessedStackInput) => {
5252
: null;
5353

5454
// Agent
55+
if (params.crossAccountBedrockRoleArn) {
56+
if (params.agentEnabled || params.searchApiKey) {
57+
throw new Error(
58+
'When `crossAccountBedrockRoleArn` is specified, the `agentEnabled` and `searchApiKey` parameters are not supported. Please create agents in the other account and specify them in the `agents` parameter.'
59+
);
60+
}
61+
}
5562
const agentStack = params.agentEnabled
5663
? new AgentStack(app, `WebSearchAgentStack${params.env}`, {
5764
env: {

0 commit comments

Comments
 (0)