@aws/nx-plugin 0.60.2 → 0.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-THIRD-PARTY +678 -2016
- package/package.json +11 -11
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +27 -33
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +13 -11
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +88 -418
- package/src/py/strands-agent/__snapshots__/generator.spec.ts.snap +88 -414
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +14 -12
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +13 -11
- package/src/ts/lib/__snapshots__/generator.spec.ts.snap +4 -4
- package/src/ts/lib/eslint.js +1 -1
- package/src/ts/lib/eslint.js.map +1 -1
- package/src/ts/lib/generator.js +13 -1
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/lib/vitest.js +3 -3
- package/src/ts/lib/vitest.js.map +1 -1
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +86 -416
- package/src/ts/nx-plugin/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +112 -94
- package/src/ts/react-website/app/files/app/src/components/AppLayout/index.tsx.template +5 -2
- package/src/ts/react-website/app/generator.js +1 -1
- package/src/ts/react-website/app/generator.js.map +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.js +3 -4
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +23 -19
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +5 -3
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +53 -222
- package/src/utils/api-constructs/files/cdk/app/apis/rest/__apiNameKebabCase__.ts.template +13 -16
- package/src/utils/versions.d.ts +52 -51
- package/src/utils/versions.js +51 -50
- package/src/utils/versions.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/core/agent-core/runtime.ts.template +0 -159
|
@@ -1,168 +1,5 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
-
exports[`ts#mcp-server generator > should match snapshot for BedrockAgentCoreRuntime generated constructs files > agent-core-runtime.ts 1`] = `
|
|
4
|
-
"import {
|
|
5
|
-
Role,
|
|
6
|
-
ServicePrincipal,
|
|
7
|
-
PolicyStatement,
|
|
8
|
-
Effect,
|
|
9
|
-
PolicyDocument,
|
|
10
|
-
IGrantable,
|
|
11
|
-
Grant,
|
|
12
|
-
IPrincipal,
|
|
13
|
-
} from 'aws-cdk-lib/aws-iam';
|
|
14
|
-
import { Construct } from 'constructs';
|
|
15
|
-
import { Stack } from 'aws-cdk-lib';
|
|
16
|
-
import { CfnRuntime } from 'aws-cdk-lib/aws-bedrockagentcore';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Options for the AgentCoreRuntime construct
|
|
20
|
-
*/
|
|
21
|
-
export interface AgentCoreRuntimeProps {
|
|
22
|
-
runtimeName: string;
|
|
23
|
-
description?: string;
|
|
24
|
-
containerUri: string;
|
|
25
|
-
serverProtocol: 'MCP' | 'HTTP';
|
|
26
|
-
environment?: Record<string, string>;
|
|
27
|
-
authorizerConfiguration?: CfnRuntime.AuthorizerConfigurationProperty;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* A construct for creating a Bedrock AgentCore Runtime
|
|
32
|
-
*/
|
|
33
|
-
export class AgentCoreRuntime extends Construct implements IGrantable {
|
|
34
|
-
public readonly role: Role;
|
|
35
|
-
public readonly arn: string;
|
|
36
|
-
|
|
37
|
-
public readonly grantPrincipal: IPrincipal;
|
|
38
|
-
|
|
39
|
-
constructor(scope: Construct, id: string, props: AgentCoreRuntimeProps) {
|
|
40
|
-
super(scope, id);
|
|
41
|
-
|
|
42
|
-
const region = Stack.of(this).region;
|
|
43
|
-
const accountId = Stack.of(this).account;
|
|
44
|
-
|
|
45
|
-
this.role = new Role(this, 'AgentCoreRole', {
|
|
46
|
-
assumedBy: new ServicePrincipal('bedrock-agentcore.amazonaws.com'),
|
|
47
|
-
inlinePolicies: {
|
|
48
|
-
AgentCorePolicy: new PolicyDocument({
|
|
49
|
-
statements: [
|
|
50
|
-
new PolicyStatement({
|
|
51
|
-
sid: 'ECRImageAccess',
|
|
52
|
-
effect: Effect.ALLOW,
|
|
53
|
-
actions: ['ecr:BatchGetImage', 'ecr:GetDownloadUrlForLayer'],
|
|
54
|
-
resources: [\`arn:aws:ecr:\${region}:\${accountId}:repository/*\`],
|
|
55
|
-
}),
|
|
56
|
-
new PolicyStatement({
|
|
57
|
-
effect: Effect.ALLOW,
|
|
58
|
-
actions: ['logs:DescribeLogStreams', 'logs:CreateLogGroup'],
|
|
59
|
-
resources: [
|
|
60
|
-
\`arn:aws:logs:\${region}:\${accountId}:log-group:/aws/bedrock-agentcore/runtimes/*\`,
|
|
61
|
-
],
|
|
62
|
-
}),
|
|
63
|
-
new PolicyStatement({
|
|
64
|
-
effect: Effect.ALLOW,
|
|
65
|
-
actions: ['logs:DescribeLogGroups'],
|
|
66
|
-
resources: [\`arn:aws:logs:\${region}:\${accountId}:log-group:*\`],
|
|
67
|
-
}),
|
|
68
|
-
new PolicyStatement({
|
|
69
|
-
effect: Effect.ALLOW,
|
|
70
|
-
actions: ['logs:CreateLogStream', 'logs:PutLogEvents'],
|
|
71
|
-
resources: [
|
|
72
|
-
\`arn:aws:logs:\${region}:\${accountId}:log-group:/aws/bedrock-agentcore/runtimes/*:log-stream:*\`,
|
|
73
|
-
],
|
|
74
|
-
}),
|
|
75
|
-
new PolicyStatement({
|
|
76
|
-
sid: 'ECRTokenAccess',
|
|
77
|
-
effect: Effect.ALLOW,
|
|
78
|
-
actions: ['ecr:GetAuthorizationToken'],
|
|
79
|
-
resources: ['*'],
|
|
80
|
-
}),
|
|
81
|
-
new PolicyStatement({
|
|
82
|
-
effect: Effect.ALLOW,
|
|
83
|
-
actions: [
|
|
84
|
-
'xray:PutTraceSegments',
|
|
85
|
-
'xray:PutTelemetryRecords',
|
|
86
|
-
'xray:GetSamplingRules',
|
|
87
|
-
'xray:GetSamplingTargets',
|
|
88
|
-
],
|
|
89
|
-
resources: ['*'],
|
|
90
|
-
}),
|
|
91
|
-
new PolicyStatement({
|
|
92
|
-
effect: Effect.ALLOW,
|
|
93
|
-
actions: ['cloudwatch:PutMetricData'],
|
|
94
|
-
resources: ['*'],
|
|
95
|
-
conditions: {
|
|
96
|
-
StringEquals: {
|
|
97
|
-
'cloudwatch:namespace': 'bedrock-agentcore',
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
}),
|
|
101
|
-
new PolicyStatement({
|
|
102
|
-
sid: 'GetAgentAccessToken',
|
|
103
|
-
effect: Effect.ALLOW,
|
|
104
|
-
actions: [
|
|
105
|
-
'bedrock-agentcore:GetWorkloadAccessToken',
|
|
106
|
-
'bedrock-agentcore:GetWorkloadAccessTokenForJWT',
|
|
107
|
-
'bedrock-agentcore:GetWorkloadAccessTokenForUserId',
|
|
108
|
-
],
|
|
109
|
-
resources: [
|
|
110
|
-
\`arn:aws:bedrock-agentcore:\${region}:\${accountId}:workload-identity-directory/default\`,
|
|
111
|
-
\`arn:aws:bedrock-agentcore:\${region}:\${accountId}:workload-identity-directory/default/workload-identity/*\`,
|
|
112
|
-
],
|
|
113
|
-
}),
|
|
114
|
-
new PolicyStatement({
|
|
115
|
-
sid: 'BedrockModelInvocation',
|
|
116
|
-
effect: Effect.ALLOW,
|
|
117
|
-
actions: [
|
|
118
|
-
'bedrock:InvokeModel',
|
|
119
|
-
'bedrock:InvokeModelWithResponseStream',
|
|
120
|
-
],
|
|
121
|
-
resources: [
|
|
122
|
-
'arn:aws:bedrock:*::foundation-model/*',
|
|
123
|
-
\`arn:aws:bedrock:\${region}:\${accountId}:*\`,
|
|
124
|
-
],
|
|
125
|
-
}),
|
|
126
|
-
],
|
|
127
|
-
}),
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
this.grantPrincipal = this.role.grantPrincipal;
|
|
131
|
-
|
|
132
|
-
const agentRuntime = new CfnRuntime(this, 'MCPServerRuntime', {
|
|
133
|
-
agentRuntimeName: props.runtimeName,
|
|
134
|
-
agentRuntimeArtifact: {
|
|
135
|
-
containerConfiguration: {
|
|
136
|
-
containerUri: props.containerUri,
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
description: props.description,
|
|
140
|
-
environmentVariables: props.environment,
|
|
141
|
-
networkConfiguration: {
|
|
142
|
-
networkMode: 'PUBLIC',
|
|
143
|
-
},
|
|
144
|
-
protocolConfiguration: props.serverProtocol,
|
|
145
|
-
roleArn: this.role.roleArn,
|
|
146
|
-
authorizerConfiguration: props.authorizerConfiguration,
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
this.arn = agentRuntime.attrAgentRuntimeArn;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Grant permissions to invoke the agent runtime (if using IAM auth - not required for JWT auth)
|
|
154
|
-
*/
|
|
155
|
-
public grantInvoke = (grantee: IGrantable) => {
|
|
156
|
-
Grant.addToPrincipal({
|
|
157
|
-
grantee,
|
|
158
|
-
actions: ['bedrock-agentcore:InvokeAgentRuntime'],
|
|
159
|
-
resourceArns: [this.arn, \`\${this.arn}/*\`],
|
|
160
|
-
});
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
"
|
|
164
|
-
`;
|
|
165
|
-
|
|
166
3
|
exports[`ts#mcp-server generator > should match snapshot for BedrockAgentCoreRuntime generated constructs files > app-index.ts 1`] = `
|
|
167
4
|
"export * from './mcp-servers/index.js';
|
|
168
5
|
"
|
|
@@ -177,24 +14,26 @@ export * from './runtime-config.js';
|
|
|
177
14
|
|
|
178
15
|
exports[`ts#mcp-server generator > should match snapshot for BedrockAgentCoreRuntime generated constructs files > mcp-server-construct.ts 1`] = `
|
|
179
16
|
"import { Lazy, Names } from 'aws-cdk-lib';
|
|
180
|
-
import {
|
|
17
|
+
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
|
|
181
18
|
import { Construct } from 'constructs';
|
|
182
19
|
import { execSync } from 'child_process';
|
|
183
20
|
import * as path from 'path';
|
|
184
21
|
import * as url from 'url';
|
|
185
22
|
import {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
23
|
+
AgentRuntimeArtifact,
|
|
24
|
+
ProtocolType,
|
|
25
|
+
Runtime,
|
|
26
|
+
RuntimeProps,
|
|
27
|
+
} from '@aws-cdk/aws-bedrock-agentcore-alpha';
|
|
189
28
|
|
|
190
29
|
export type SnapshotBedrockServerProps = Omit<
|
|
191
|
-
|
|
192
|
-
'runtimeName' | '
|
|
30
|
+
RuntimeProps,
|
|
31
|
+
'runtimeName' | 'protocolConfiguration' | 'agentRuntimeArtifact'
|
|
193
32
|
>;
|
|
194
33
|
|
|
195
34
|
export class SnapshotBedrockServer extends Construct {
|
|
196
|
-
public readonly dockerImage:
|
|
197
|
-
public readonly agentCoreRuntime:
|
|
35
|
+
public readonly dockerImage: AgentRuntimeArtifact;
|
|
36
|
+
public readonly agentCoreRuntime: Runtime;
|
|
198
37
|
|
|
199
38
|
constructor(
|
|
200
39
|
scope: Construct,
|
|
@@ -203,28 +42,26 @@ export class SnapshotBedrockServer extends Construct {
|
|
|
203
42
|
) {
|
|
204
43
|
super(scope, id);
|
|
205
44
|
|
|
206
|
-
this.dockerImage =
|
|
207
|
-
|
|
208
|
-
directory: path.dirname(url.fileURLToPath(new URL(import.meta.url))),
|
|
209
|
-
extraHash: execSync(
|
|
210
|
-
\`docker inspect proj-snapshot-bedrock-server:latest --format '{{.Id}}'\`,
|
|
211
|
-
{ encoding: 'utf-8' },
|
|
212
|
-
).trim(),
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
this.agentCoreRuntime = new AgentCoreRuntime(
|
|
216
|
-
this,
|
|
217
|
-
'SnapshotBedrockServer',
|
|
45
|
+
this.dockerImage = AgentRuntimeArtifact.fromAsset(
|
|
46
|
+
path.dirname(url.fileURLToPath(new URL(import.meta.url))),
|
|
218
47
|
{
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
containerUri: this.dockerImage.imageUri,
|
|
225
|
-
...props,
|
|
48
|
+
platform: Platform.LINUX_ARM64,
|
|
49
|
+
extraHash: execSync(
|
|
50
|
+
\`docker inspect proj-snapshot-bedrock-server:latest --format '{{.Id}}'\`,
|
|
51
|
+
{ encoding: 'utf-8' },
|
|
52
|
+
).trim(),
|
|
226
53
|
},
|
|
227
54
|
);
|
|
55
|
+
|
|
56
|
+
this.agentCoreRuntime = new Runtime(this, 'SnapshotBedrockServer', {
|
|
57
|
+
runtimeName: Lazy.string({
|
|
58
|
+
produce: () =>
|
|
59
|
+
Names.uniqueResourceName(this.agentCoreRuntime, { maxLength: 40 }),
|
|
60
|
+
}),
|
|
61
|
+
protocolConfiguration: ProtocolType.MCP,
|
|
62
|
+
agentRuntimeArtifact: this.dockerImage,
|
|
63
|
+
...props,
|
|
64
|
+
});
|
|
228
65
|
}
|
|
229
66
|
}
|
|
230
67
|
"
|
|
@@ -242,16 +79,12 @@ exports[`ts#mcp-server generator > should match snapshot for Terraform generated
|
|
|
242
79
|
required_providers {
|
|
243
80
|
aws = {
|
|
244
81
|
source = "hashicorp/aws"
|
|
245
|
-
version = ">= 6.
|
|
82
|
+
version = ">= 6.23"
|
|
246
83
|
}
|
|
247
84
|
null = {
|
|
248
85
|
source = "hashicorp/null"
|
|
249
86
|
version = ">= 3.0"
|
|
250
87
|
}
|
|
251
|
-
local = {
|
|
252
|
-
source = "hashicorp/local"
|
|
253
|
-
version = ">= 2.0"
|
|
254
|
-
}
|
|
255
88
|
random = {
|
|
256
89
|
source = "hashicorp/random"
|
|
257
90
|
version = ">= 3.0"
|
|
@@ -270,20 +103,23 @@ variable "agent_runtime_name" {
|
|
|
270
103
|
}
|
|
271
104
|
|
|
272
105
|
variable "server_protocol" {
|
|
273
|
-
description = "
|
|
106
|
+
description = "Server protocol for the agent runtime (HTTP, MCP, or A2A)"
|
|
274
107
|
type = string
|
|
108
|
+
default = "HTTP"
|
|
275
109
|
validation {
|
|
276
|
-
condition = contains(["MCP", "HTTP"], var.server_protocol)
|
|
277
|
-
error_message = "Protocol type must be either 'MCP' or '
|
|
110
|
+
condition = contains(["MCP", "HTTP", "A2A"], var.server_protocol)
|
|
111
|
+
error_message = "Protocol type must be either 'MCP', 'HTTP', or 'A2A'."
|
|
278
112
|
}
|
|
279
113
|
}
|
|
280
114
|
|
|
281
|
-
variable "
|
|
282
|
-
description = "
|
|
115
|
+
variable "authorizer_configuration" {
|
|
116
|
+
description = "Authorization configuration for authenticating incoming requests"
|
|
283
117
|
type = object({
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
118
|
+
custom_jwt_authorizer = optional(object({
|
|
119
|
+
discovery_url = string
|
|
120
|
+
allowed_audience = optional(list(string))
|
|
121
|
+
allowed_clients = optional(list(string))
|
|
122
|
+
}))
|
|
287
123
|
})
|
|
288
124
|
default = null
|
|
289
125
|
}
|
|
@@ -321,7 +157,7 @@ data "aws_region" "current" {}
|
|
|
321
157
|
|
|
322
158
|
locals {
|
|
323
159
|
aws_account_id = data.aws_caller_identity.current.account_id
|
|
324
|
-
aws_region
|
|
160
|
+
aws_region = data.aws_region.current.id
|
|
325
161
|
}
|
|
326
162
|
|
|
327
163
|
# Random ID for bucket suffix to ensure uniqueness
|
|
@@ -332,7 +168,7 @@ resource "random_id" "unique_suffix" {
|
|
|
332
168
|
# ECR Repository
|
|
333
169
|
resource "aws_ecr_repository" "agent_core_repository" {
|
|
334
170
|
#checkov:skip=CKV_AWS_136:AES256 encryption is sufficient for ECR repositories
|
|
335
|
-
name
|
|
171
|
+
name = "\${lower(var.agent_runtime_name)}_repository_\${random_id.unique_suffix.hex}"
|
|
336
172
|
|
|
337
173
|
#checkov:skip=CKV_AWS_51:Image tag is reused for latest deployments
|
|
338
174
|
image_tag_mutability = "MUTABLE"
|
|
@@ -401,7 +237,7 @@ resource "aws_iam_role" "agent_core_runtime_role" {
|
|
|
401
237
|
tags = var.tags
|
|
402
238
|
}
|
|
403
239
|
|
|
404
|
-
# IAM Policy for
|
|
240
|
+
# IAM Policy for Agent Core Runtime
|
|
405
241
|
resource "aws_iam_policy" "agent_core_runtime_policy" {
|
|
406
242
|
name = "\${var.agent_runtime_name}-QueryAgentPolicy-\${random_id.unique_suffix.hex}"
|
|
407
243
|
description = "Restricted policy for Agent"
|
|
@@ -417,7 +253,7 @@ resource "aws_iam_policy" "agent_core_runtime_policy" {
|
|
|
417
253
|
"ecr:GetDownloadUrlForLayer"
|
|
418
254
|
]
|
|
419
255
|
Resource = [
|
|
420
|
-
|
|
256
|
+
aws_ecr_repository.agent_core_repository.arn
|
|
421
257
|
]
|
|
422
258
|
},
|
|
423
259
|
{
|
|
@@ -491,17 +327,6 @@ resource "aws_iam_policy" "agent_core_runtime_policy" {
|
|
|
491
327
|
"arn:aws:bedrock-agentcore:\${local.aws_region}:\${local.aws_account_id}:workload-identity-directory/default",
|
|
492
328
|
"arn:aws:bedrock-agentcore:\${local.aws_region}:\${local.aws_account_id}:workload-identity-directory/default/workload-identity/*"
|
|
493
329
|
]
|
|
494
|
-
},
|
|
495
|
-
{ "Sid" : "BedrockModelInvocation",
|
|
496
|
-
"Effect" : "Allow",
|
|
497
|
-
"Action" : [
|
|
498
|
-
"bedrock:InvokeModel",
|
|
499
|
-
"bedrock:InvokeModelWithResponseStream"
|
|
500
|
-
],
|
|
501
|
-
"Resource" : [
|
|
502
|
-
"arn:aws:bedrock:*::foundation-model/*",
|
|
503
|
-
"arn:aws:bedrock:\${local.aws_region}:\${local.aws_account_id}:*"
|
|
504
|
-
]
|
|
505
330
|
}
|
|
506
331
|
], var.additional_iam_policy_statements)
|
|
507
332
|
})
|
|
@@ -515,6 +340,7 @@ resource "aws_iam_role_policy_attachment" "agent_core_policy" {
|
|
|
515
340
|
policy_arn = aws_iam_policy.agent_core_runtime_policy.arn
|
|
516
341
|
}
|
|
517
342
|
|
|
343
|
+
# Data source to get Docker image digest
|
|
518
344
|
data "external" "docker_digest" {
|
|
519
345
|
program = ["sh", "-c", "echo '{\\"digest\\":\\"'$(docker inspect \${var.docker_image_tag} --format '{{.Id}}')'\\"}' "]
|
|
520
346
|
}
|
|
@@ -522,9 +348,7 @@ data "external" "docker_digest" {
|
|
|
522
348
|
# Null resource for Docker publish
|
|
523
349
|
resource "null_resource" "docker_publish" {
|
|
524
350
|
triggers = {
|
|
525
|
-
# Trigger rebuild when the image changes
|
|
526
351
|
docker_digest = data.external.docker_digest.result.digest
|
|
527
|
-
|
|
528
352
|
repository_url = aws_ecr_repository.agent_core_repository.repository_url
|
|
529
353
|
docker_image_tag = var.docker_image_tag
|
|
530
354
|
}
|
|
@@ -545,206 +369,45 @@ resource "null_resource" "docker_publish" {
|
|
|
545
369
|
depends_on = [aws_ecr_repository_policy.agent_core_ecr_policy]
|
|
546
370
|
}
|
|
547
371
|
|
|
548
|
-
#
|
|
549
|
-
resource "
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
config_hash = md5(join("", [jsonencode(var.customJWTAuthorizer), var.server_protocol]))
|
|
554
|
-
env_hash = md5(jsonencode(var.env))
|
|
555
|
-
}
|
|
372
|
+
# Bedrock AgentCore Agent Runtime
|
|
373
|
+
resource "aws_bedrockagentcore_agent_runtime" "agent_runtime" {
|
|
374
|
+
agent_runtime_name = "\${var.agent_runtime_name}_\${random_id.unique_suffix.hex}"
|
|
375
|
+
description = "Agent Runtime for \${var.agent_runtime_name}"
|
|
376
|
+
role_arn = aws_iam_role.agent_core_runtime_role.arn
|
|
556
377
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
import json
|
|
562
|
-
import sys
|
|
563
|
-
|
|
564
|
-
# Create the client
|
|
565
|
-
client = boto3.client("bedrock-agentcore-control", region_name="\${local.aws_region}")
|
|
566
|
-
|
|
567
|
-
# Environment variables for QueryAgentConfig
|
|
568
|
-
environment_variables = json.loads("""\${jsonencode(var.env)}""")
|
|
569
|
-
agent_name = "\${var.agent_runtime_name}_\${random_id.unique_suffix.hex}"
|
|
570
|
-
authorization_config = json.loads("""{"customJWTAuthorizer": \${jsonencode(var.customJWTAuthorizer != null ? {
|
|
571
|
-
for k, v in var.customJWTAuthorizer : k => v if v != null
|
|
572
|
-
} : {})}}""")
|
|
573
|
-
|
|
574
|
-
try:
|
|
575
|
-
# First, check if an agent runtime with this name already exists
|
|
576
|
-
existing_agent_runtime_id = None
|
|
577
|
-
try:
|
|
578
|
-
list_response = client.list_agent_runtimes()
|
|
579
|
-
for runtime in list_response.get("agentRuntimes", []):
|
|
580
|
-
if runtime.get("agentRuntimeName") == agent_name:
|
|
581
|
-
existing_agent_runtime_id = runtime.get("agentRuntimeId")
|
|
582
|
-
print(f"Found existing agent runtime with ID: {existing_agent_runtime_id}")
|
|
583
|
-
break
|
|
584
|
-
except Exception as e:
|
|
585
|
-
print(f"Error listing agent runtimes: {e}")
|
|
586
|
-
|
|
587
|
-
if existing_agent_runtime_id:
|
|
588
|
-
# Update the existing agent runtime
|
|
589
|
-
try:
|
|
590
|
-
update_response = client.update_agent_runtime(
|
|
591
|
-
agentRuntimeId=existing_agent_runtime_id,
|
|
592
|
-
agentRuntimeArtifact={
|
|
593
|
-
"containerConfiguration": {
|
|
594
|
-
"containerUri": "\${aws_ecr_repository.agent_core_repository.repository_url}:latest"
|
|
595
|
-
}
|
|
596
|
-
},
|
|
597
|
-
environmentVariables=environment_variables,
|
|
598
|
-
networkConfiguration={"networkMode": "PUBLIC"},
|
|
599
|
-
protocolConfiguration={"serverProtocol": "\${var.server_protocol}"},
|
|
600
|
-
\${var.customJWTAuthorizer == null ? "" : "authorizerConfiguration=authorization_config,"}
|
|
601
|
-
roleArn="\${aws_iam_role.agent_core_runtime_role.arn}"
|
|
602
|
-
)
|
|
603
|
-
agent_runtime_id = existing_agent_runtime_id
|
|
604
|
-
print(f"Agent runtime updated successfully: {agent_runtime_id}")
|
|
605
|
-
except Exception as e:
|
|
606
|
-
print(f"Error updating agent runtime: {e}")
|
|
607
|
-
# If update fails, try to create a new one
|
|
608
|
-
existing_agent_runtime_id = None
|
|
609
|
-
|
|
610
|
-
if not existing_agent_runtime_id:
|
|
611
|
-
# Agent runtime doesn"t exist or update failed, create it
|
|
612
|
-
response = client.create_agent_runtime(
|
|
613
|
-
agentRuntimeName=agent_name,
|
|
614
|
-
agentRuntimeArtifact={
|
|
615
|
-
"containerConfiguration": {
|
|
616
|
-
"containerUri": "\${aws_ecr_repository.agent_core_repository.repository_url}:latest"
|
|
617
|
-
}
|
|
618
|
-
},
|
|
619
|
-
environmentVariables=environment_variables,
|
|
620
|
-
networkConfiguration={"networkMode": "PUBLIC"},
|
|
621
|
-
protocolConfiguration={"serverProtocol": "\${var.server_protocol}"},
|
|
622
|
-
\${var.customJWTAuthorizer == null ? "" : "authorizerConfiguration=authorization_config,"}
|
|
623
|
-
roleArn="\${aws_iam_role.agent_core_runtime_role.arn}"
|
|
624
|
-
)
|
|
625
|
-
|
|
626
|
-
agent_runtime_id = response.get("agentRuntimeId", "")
|
|
627
|
-
print(f"Agent runtime created successfully with ID: {agent_runtime_id}")
|
|
628
|
-
|
|
629
|
-
except Exception as e:
|
|
630
|
-
print(f"Error managing agent runtime: {str(e)}")
|
|
631
|
-
sys.exit(1)
|
|
632
|
-
'
|
|
633
|
-
EOT
|
|
378
|
+
agent_runtime_artifact {
|
|
379
|
+
container_configuration {
|
|
380
|
+
container_uri = "\${aws_ecr_repository.agent_core_repository.repository_url}:latest"
|
|
381
|
+
}
|
|
634
382
|
}
|
|
635
383
|
|
|
636
|
-
|
|
637
|
-
null_resource.docker_publish,
|
|
638
|
-
aws_iam_role_policy_attachment.agent_core_policy
|
|
639
|
-
]
|
|
640
|
-
}
|
|
384
|
+
environment_variables = length(var.env) > 0 ? var.env : null
|
|
641
385
|
|
|
386
|
+
dynamic "authorizer_configuration" {
|
|
387
|
+
for_each = var.authorizer_configuration != null && var.authorizer_configuration.custom_jwt_authorizer != null ? [var.authorizer_configuration.custom_jwt_authorizer] : []
|
|
388
|
+
content {
|
|
389
|
+
custom_jwt_authorizer {
|
|
390
|
+
discovery_url = authorizer_configuration.value.discovery_url
|
|
391
|
+
allowed_audience = authorizer_configuration.value.allowed_audience
|
|
392
|
+
allowed_clients = authorizer_configuration.value.allowed_clients
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
642
396
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
triggers = {
|
|
646
|
-
aws_region = local.aws_region
|
|
647
|
-
agent_name = var.agent_runtime_name
|
|
648
|
-
unique_suffix = random_id.unique_suffix.hex
|
|
397
|
+
network_configuration {
|
|
398
|
+
network_mode = "PUBLIC"
|
|
649
399
|
}
|
|
650
400
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
command = <<-EOT
|
|
654
|
-
uv run --with boto3 python -c "
|
|
655
|
-
import boto3
|
|
656
|
-
import json
|
|
657
|
-
import os
|
|
658
|
-
|
|
659
|
-
# Create the client
|
|
660
|
-
client = boto3.client('bedrock-agentcore-control', region_name='\${self.triggers.aws_region}')
|
|
661
|
-
|
|
662
|
-
agent_name = '\${self.triggers.agent_name}_\${self.triggers.unique_suffix}'
|
|
663
|
-
|
|
664
|
-
try:
|
|
665
|
-
# Find the agent runtime by name
|
|
666
|
-
agent_runtime_id = None
|
|
667
|
-
try:
|
|
668
|
-
list_response = client.list_agent_runtimes()
|
|
669
|
-
for runtime in list_response.get('agentRuntimes', []):
|
|
670
|
-
if runtime.get('agentRuntimeName') == agent_name:
|
|
671
|
-
agent_runtime_id = runtime.get('agentRuntimeId')
|
|
672
|
-
print(f'Found agent runtime to delete: {agent_name} (ID: {agent_runtime_id})')
|
|
673
|
-
break
|
|
674
|
-
except Exception as e:
|
|
675
|
-
print(f'Error listing agent runtimes: {e}')
|
|
676
|
-
|
|
677
|
-
if not agent_runtime_id:
|
|
678
|
-
print(f'No agent runtime found with name: {agent_name}')
|
|
679
|
-
exit(0)
|
|
680
|
-
|
|
681
|
-
# Delete the agent runtime using the found ID
|
|
682
|
-
response = client.delete_agent_runtime(
|
|
683
|
-
agentRuntimeId=agent_runtime_id
|
|
684
|
-
)
|
|
685
|
-
print(f'Agent runtime {agent_name} (ID: {agent_runtime_id}) deleted successfully:', json.dumps(response, indent=2, default=str))
|
|
686
|
-
|
|
687
|
-
except client.exceptions.ResourceNotFoundException:
|
|
688
|
-
print(f'Agent runtime {agent_name} not found, may have been already deleted')
|
|
689
|
-
except Exception as e:
|
|
690
|
-
print(f'Error deleting agent runtime {agent_name}:', str(e))
|
|
691
|
-
# Don't exit with error code during destroy to avoid blocking cleanup
|
|
692
|
-
"
|
|
693
|
-
EOT
|
|
401
|
+
protocol_configuration {
|
|
402
|
+
server_protocol = var.server_protocol
|
|
694
403
|
}
|
|
695
404
|
|
|
696
|
-
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
# Data source to find the agent runtime by name and get its ID
|
|
700
|
-
data "external" "agent_runtime_lookup" {
|
|
701
|
-
program = ["uv", "run", "--with", "boto3", "python", "-c", <<-EOT
|
|
702
|
-
import boto3
|
|
703
|
-
import json
|
|
704
|
-
import sys
|
|
705
|
-
|
|
706
|
-
# Create the client
|
|
707
|
-
client = boto3.client("bedrock-agentcore-control", region_name="\${local.aws_region}")
|
|
708
|
-
|
|
709
|
-
agent_name = "\${var.agent_runtime_name}_\${random_id.unique_suffix.hex}"
|
|
710
|
-
|
|
711
|
-
try:
|
|
712
|
-
# Find the agent runtime by name
|
|
713
|
-
list_response = client.list_agent_runtimes()
|
|
714
|
-
for runtime in list_response.get("agentRuntimes", []):
|
|
715
|
-
if runtime.get("agentRuntimeName") == agent_name:
|
|
716
|
-
agent_runtime_id = runtime.get("agentRuntimeId")
|
|
717
|
-
runtime_arn = f"arn:aws:bedrock-agentcore:\${local.aws_region}:\${local.aws_account_id}:runtime/{agent_runtime_id}"
|
|
718
|
-
|
|
719
|
-
result = {
|
|
720
|
-
"agent_runtime_id": agent_runtime_id,
|
|
721
|
-
"agent_runtime_arn": runtime_arn,
|
|
722
|
-
"agent_name": agent_name
|
|
723
|
-
}
|
|
724
|
-
print(json.dumps(result))
|
|
725
|
-
sys.exit(0)
|
|
726
|
-
|
|
727
|
-
# If not found, return empty values
|
|
728
|
-
result = {
|
|
729
|
-
"agent_runtime_id": "",
|
|
730
|
-
"agent_runtime_arn": "",
|
|
731
|
-
"agent_name": agent_name
|
|
732
|
-
}
|
|
733
|
-
print(json.dumps(result))
|
|
734
|
-
|
|
735
|
-
except Exception as e:
|
|
736
|
-
print(f"Error looking up agent runtime: {str(e)}", file=sys.stderr)
|
|
737
|
-
# Return empty values on error to avoid breaking Terraform
|
|
738
|
-
result = {
|
|
739
|
-
"agent_runtime_id": "",
|
|
740
|
-
"agent_runtime_arn": "",
|
|
741
|
-
"agent_name": agent_name
|
|
742
|
-
}
|
|
743
|
-
print(json.dumps(result))
|
|
744
|
-
EOT
|
|
745
|
-
]
|
|
405
|
+
tags = var.tags
|
|
746
406
|
|
|
747
|
-
depends_on = [
|
|
407
|
+
depends_on = [
|
|
408
|
+
null_resource.docker_publish,
|
|
409
|
+
aws_iam_role_policy.agent_core_runtime_policy
|
|
410
|
+
]
|
|
748
411
|
}
|
|
749
412
|
|
|
750
413
|
# Outputs
|
|
@@ -760,17 +423,22 @@ output "agent_core_runtime_role_name" {
|
|
|
760
423
|
|
|
761
424
|
output "agent_runtime_name" {
|
|
762
425
|
description = "Name of the deployed agent runtime"
|
|
763
|
-
value =
|
|
426
|
+
value = aws_bedrockagentcore_agent_runtime.agent_runtime.agent_runtime_name
|
|
764
427
|
}
|
|
765
428
|
|
|
766
429
|
output "agent_core_runtime_arn" {
|
|
767
430
|
description = "ARN of the Bedrock Agent Core runtime"
|
|
768
|
-
value =
|
|
431
|
+
value = aws_bedrockagentcore_agent_runtime.agent_runtime.agent_runtime_arn
|
|
769
432
|
}
|
|
770
433
|
|
|
771
434
|
output "agent_runtime_id" {
|
|
772
435
|
description = "ID of the Bedrock Agent Core runtime"
|
|
773
|
-
value =
|
|
436
|
+
value = aws_bedrockagentcore_agent_runtime.agent_runtime.agent_runtime_id
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
output "agent_runtime_version" {
|
|
440
|
+
description = "Version of the Bedrock Agent Core runtime"
|
|
441
|
+
value = aws_bedrockagentcore_agent_runtime.agent_runtime.agent_runtime_version
|
|
774
442
|
}
|
|
775
443
|
"
|
|
776
444
|
`;
|
|
@@ -803,9 +471,11 @@ module "agent_core_runtime" {
|
|
|
803
471
|
agent_runtime_name = "TerraformSnapshotServer"
|
|
804
472
|
docker_image_tag = "proj-terraform-snapshot-server:latest"
|
|
805
473
|
server_protocol = "MCP"
|
|
806
|
-
#
|
|
807
|
-
#
|
|
808
|
-
#
|
|
474
|
+
# authorizer_configuration = {
|
|
475
|
+
# custom_jwt_authorizer = {
|
|
476
|
+
# discovery_url = "https://xxx/.well-known/openid-configuration"
|
|
477
|
+
# allowed_clients = [ "xxx" ]
|
|
478
|
+
# }
|
|
809
479
|
# }
|
|
810
480
|
|
|
811
481
|
env = var.env
|
|
@@ -242,7 +242,7 @@ export const registerCreateWorkspaceCommandTool = (server: McpServer) => {
|
|
|
242
242
|
text: \`Run the following command to create a workspace:
|
|
243
243
|
|
|
244
244
|
\\\`\\\`\\\`bash
|
|
245
|
-
npx create-nx-workspace@22.
|
|
245
|
+
npx create-nx-workspace@22.1.3 \${workspaceName} --pm=\${packageManager} --preset=@aws/nx-plugin --ci=skip --aiAgents
|
|
246
246
|
\\\`\\\`\\\`
|
|
247
247
|
|
|
248
248
|
This will create a new workspace within the \${workspaceName} directory.
|