@aws/nx-plugin 1.0.0-rc.82 → 1.0.0-rc.84
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/migrations.json +41 -1
- package/package.json +1 -1
- package/src/agentcore-gateway/__snapshots__/generator.spec.ts.snap +51 -2
- package/src/agentcore-gateway/generator.d.ts +7 -6
- package/src/agentcore-gateway/generator.js +2 -12
- package/src/agentcore-gateway/generator.js.map +1 -1
- package/src/agentcore-harness/__snapshots__/generator.spec.ts.snap +4 -5
- package/src/agentcore-harness/files/project/README.md.template +4 -5
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/__snapshots__/migration.spec.ts.snap +79 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/metadata.json +3 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/migration.d.ts +6 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/migration.js +87 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/migration.js.map +1 -0
- package/src/migrations/latest/dynamodb-terraform-app-module-outputs/metadata.json +3 -0
- package/src/migrations/latest/dynamodb-terraform-app-module-outputs/migration.d.ts +6 -0
- package/src/migrations/latest/dynamodb-terraform-app-module-outputs/migration.js +69 -0
- package/src/migrations/latest/dynamodb-terraform-app-module-outputs/migration.js.map +1 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/__snapshots__/migration.spec.ts.snap +54 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/metadata.json +3 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/migration.d.ts +6 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/migration.js +86 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/migration.js.map +1 -0
- package/src/migrations/latest/terraform-data-resource-destroy-protection/__snapshots__/migration.spec.ts.snap +75 -0
- package/src/migrations/latest/terraform-data-resource-destroy-protection/metadata.json +3 -0
- package/src/migrations/latest/terraform-data-resource-destroy-protection/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-data-resource-destroy-protection/migration.js +78 -0
- package/src/migrations/latest/terraform-data-resource-destroy-protection/migration.js.map +1 -0
- package/src/migrations/latest/terraform-declare-used-providers/metadata.json +3 -0
- package/src/migrations/latest/terraform-declare-used-providers/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-declare-used-providers/migration.js +147 -0
- package/src/migrations/latest/terraform-declare-used-providers/migration.js.map +1 -0
- package/src/migrations/latest/terraform-gateway-cedar-render-root-ejs/metadata.json +3 -0
- package/src/migrations/latest/terraform-gateway-cedar-render-root-ejs/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-gateway-cedar-render-root-ejs/migration.js +38 -0
- package/src/migrations/latest/terraform-gateway-cedar-render-root-ejs/migration.js.map +1 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/__snapshots__/migration.spec.ts.snap +521 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/metadata.json +3 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration.js +504 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration.js.map +1 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/__snapshots__/migration.spec.ts.snap +286 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/metadata.json +3 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/migration.d.ts +6 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/migration.js +238 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/migration.js.map +1 -0
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +12 -0
- package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +21 -0
- package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +231 -24
- package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +8 -0
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +31 -2
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +216 -25
- package/src/terraform/project/files/application/bootstrap/providers.tf.template +9 -0
- package/src/terraform/project/files/application/src/providers.tf.template +4 -0
- package/src/terraform/project/files/library/src/main.tf.template +9 -0
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +231 -24
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +8 -0
- package/src/ts/dcr-proxy/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +21 -0
- package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +8 -0
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +74 -4
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.spec.ts.snap +35 -8
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +4 -0
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +9 -2
- package/src/utils/agent-core-constructs/agent-core-constructs.js +22 -8
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/app/agentcore-harness/__nameKebabCase__/__nameKebabCase__.ts.template +39 -1
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +8 -1
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +57 -2
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-harness/__nameKebabCase__/__nameKebabCase__.tf.template +258 -24
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +4 -0
- package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +8 -0
- package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +9 -1
- package/src/utils/api-constructs/files/terraform/core/api/rest/rest-api/rest-api.tf.template +60 -7
- package/src/utils/dcr-proxy-constructs/files/terraform/app/dcr-proxies/__nameKebabCase__/__nameKebabCase__.tf.template +4 -0
- package/src/utils/dynamodb-constructs/files/terraform/app/dynamodb/__nameKebabCase__/__nameKebabCase__.tf.template +15 -0
- package/src/utils/dynamodb-constructs/files/terraform/core/dynamodb/dynamodb.tf.template +6 -0
- package/src/utils/files/terraform/src/metrics/providers.tf.template +12 -0
- package/src/utils/function-constructs/files/terraform/app/lambda-functions/__nameKebabCase__/__nameKebabCase__.tf.template +4 -0
- package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +33 -8
- package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +4 -0
- package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +51 -2
- package/src/utils/rdb-constructs/files/cdk/core/rdb/aurora.ts.template +18 -0
- package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +15 -4
- package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +8 -2
- package/src/utils/rdb-constructs/rdb-constructs.d.ts +12 -0
- package/src/utils/rdb-constructs/rdb-constructs.js +24 -3
- package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
- package/src/utils/shared-constructs-constants.d.ts +5 -0
- package/src/utils/shared-constructs-constants.js +4 -0
- package/src/utils/shared-constructs-constants.js.map +1 -1
- package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +4 -0
package/migrations.json
CHANGED
|
@@ -32,6 +32,46 @@
|
|
|
32
32
|
"description": "Provision AppConfig configuration profiles for every namespace the vended terraform modules write to",
|
|
33
33
|
"implementation": "./src/migrations/latest/runtime-config-namespace-defaults/migration"
|
|
34
34
|
},
|
|
35
|
+
"latest-dynamodb-terraform-app-module-outputs": {
|
|
36
|
+
"version": "1.0.0-rc.83",
|
|
37
|
+
"description": "Re-export the DynamoDB table and KMS key attributes from the vended Terraform per-table app module",
|
|
38
|
+
"implementation": "./src/migrations/latest/dynamodb-terraform-app-module-outputs/migration"
|
|
39
|
+
},
|
|
40
|
+
"latest-terraform-data-resource-destroy-protection": {
|
|
41
|
+
"version": "1.0.0-rc.83",
|
|
42
|
+
"description": "Add prevent_destroy and a 30 day KMS deletion window to the vended Terraform DynamoDB table and Aurora cluster modules",
|
|
43
|
+
"implementation": "./src/migrations/latest/terraform-data-resource-destroy-protection/migration"
|
|
44
|
+
},
|
|
45
|
+
"latest-terraform-gateway-cedar-render-root-ejs": {
|
|
46
|
+
"version": "1.0.0-rc.83",
|
|
47
|
+
"description": "Declare ejs at the workspace root so the Terraform gateway's Cedar render script resolves it",
|
|
48
|
+
"implementation": "./src/migrations/latest/terraform-gateway-cedar-render-root-ejs/migration"
|
|
49
|
+
},
|
|
50
|
+
"latest-rdb-terraform-aurora-app-module-defaults": {
|
|
51
|
+
"version": "1.0.0-rc.84",
|
|
52
|
+
"description": "Align the vended Terraform Aurora app module variable defaults with the core module, enabling CloudWatch engine log export and exposing enable_key_rotation",
|
|
53
|
+
"implementation": "./src/migrations/latest/rdb-terraform-aurora-app-module-defaults/migration"
|
|
54
|
+
},
|
|
55
|
+
"latest-agentcore-harness-no-tools-by-default": {
|
|
56
|
+
"version": "1.0.0-rc.84",
|
|
57
|
+
"description": "Pin the vended AgentCore Harness construct/module to no tools by default, since AgentCore treats an absent allowedTools as every tool",
|
|
58
|
+
"implementation": "./src/migrations/latest/agentcore-harness-no-tools-by-default/migration"
|
|
59
|
+
},
|
|
60
|
+
"latest-terraform-declare-used-providers": {
|
|
61
|
+
"version": "1.0.0-rc.84",
|
|
62
|
+
"description": "Declare every provider each vended Terraform module uses in its own required_providers",
|
|
63
|
+
"implementation": "./src/migrations/latest/terraform-declare-used-providers/migration"
|
|
64
|
+
},
|
|
65
|
+
"latest-waf-log-group-cmk-encryption": {
|
|
66
|
+
"version": "1.0.0-rc.84",
|
|
67
|
+
"description": "Encrypt vended WAF log groups with a customer-managed KMS key",
|
|
68
|
+
"implementation": "./src/migrations/latest/waf-log-group-cmk-encryption/migration"
|
|
69
|
+
},
|
|
70
|
+
"latest-terraform-harness-vpc-role-and-memory-grant": {
|
|
71
|
+
"version": "1.0.0-rc.84",
|
|
72
|
+
"description": "Add VPC, execution role and native field support to the vended Terraform AgentCore Harness module, and scope its managed-memory grant to the service-assigned ARN",
|
|
73
|
+
"implementation": "./src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration"
|
|
74
|
+
},
|
|
35
75
|
"v1.0.0-rc.50-0001-modernize-function-props-cast": {
|
|
36
76
|
"version": "1.0.0-rc.50",
|
|
37
77
|
"description": "Replace the legacy angle-bracket FunctionProps type assertion with the modern as syntax in generated API constructs",
|
|
@@ -173,7 +213,7 @@
|
|
|
173
213
|
"implementation": "./src/migrations/v1.0.0-rc.75/0001-ts-agent-session-id-middleware-extraction/migration"
|
|
174
214
|
},
|
|
175
215
|
"sync-vended-versions": {
|
|
176
|
-
"version": "1.0.0-rc.
|
|
216
|
+
"version": "1.0.0-rc.84",
|
|
177
217
|
"description": "Sync vended dependency versions and the tracked plugin version to those vended by this release",
|
|
178
218
|
"implementation": "./src/utils/version-upgrade-migration/migration"
|
|
179
219
|
}
|
package/package.json
CHANGED
|
@@ -43,6 +43,8 @@ data "aws_region" "current" {}
|
|
|
43
43
|
locals {
|
|
44
44
|
aws_account_id = data.aws_caller_identity.current.account_id
|
|
45
45
|
aws_region = data.aws_region.current.id
|
|
46
|
+
|
|
47
|
+
gateway_waf_log_group_name = var.enable_waf ? "aws-waf-logs-my-gateway-\${random_id.unique_suffix.hex}" : null
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
resource "random_id" "unique_suffix" {
|
|
@@ -205,14 +207,61 @@ resource "aws_wafv2_web_acl_association" "gateway_waf" {
|
|
|
205
207
|
web_acl_arn = aws_wafv2_web_acl.gateway_waf[0].arn
|
|
206
208
|
}
|
|
207
209
|
|
|
210
|
+
# KMS key for encrypting WAF request logs at rest
|
|
211
|
+
resource "aws_kms_key" "gateway_waf_logs" {
|
|
212
|
+
count = var.enable_waf ? 1 : 0
|
|
213
|
+
|
|
214
|
+
description = "MyGateway gateway WAF log encryption"
|
|
215
|
+
deletion_window_in_days = 7
|
|
216
|
+
enable_key_rotation = true
|
|
217
|
+
|
|
218
|
+
policy = jsonencode({
|
|
219
|
+
Version = "2012-10-17"
|
|
220
|
+
Statement = [
|
|
221
|
+
{
|
|
222
|
+
Sid = "Enable IAM User Permissions"
|
|
223
|
+
Effect = "Allow"
|
|
224
|
+
Principal = { AWS = "arn:aws:iam::\${local.aws_account_id}:root" }
|
|
225
|
+
Action = "kms:*"
|
|
226
|
+
Resource = "*"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
Sid = "Allow CloudWatch Logs"
|
|
230
|
+
Effect = "Allow"
|
|
231
|
+
Principal = { Service = "logs.\${local.aws_region}.amazonaws.com" }
|
|
232
|
+
Action = [
|
|
233
|
+
"kms:Encrypt",
|
|
234
|
+
"kms:Decrypt",
|
|
235
|
+
"kms:ReEncrypt*",
|
|
236
|
+
"kms:GenerateDataKey*",
|
|
237
|
+
"kms:DescribeKey"
|
|
238
|
+
]
|
|
239
|
+
Resource = "*"
|
|
240
|
+
Condition = {
|
|
241
|
+
ArnEquals = {
|
|
242
|
+
"kms:EncryptionContext:aws:logs:arn" = "arn:aws:logs:\${local.aws_region}:\${local.aws_account_id}:log-group:\${local.gateway_waf_log_group_name}"
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
resource "aws_kms_alias" "gateway_waf_logs" {
|
|
251
|
+
count = var.enable_waf ? 1 : 0
|
|
252
|
+
|
|
253
|
+
name = "alias/my-gateway-\${random_id.unique_suffix.hex}-waf-logs"
|
|
254
|
+
target_key_id = aws_kms_key.gateway_waf_logs[0].key_id
|
|
255
|
+
}
|
|
256
|
+
|
|
208
257
|
# WAF request logs. WAFv2 requires the \`aws-waf-logs-\` name prefix.
|
|
209
258
|
resource "aws_cloudwatch_log_group" "gateway_waf_logs" {
|
|
210
|
-
#checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
|
|
211
259
|
#checkov:skip=CKV_AWS_338:Log retention set to one year which is sufficient for WAF logs
|
|
212
260
|
count = var.enable_waf ? 1 : 0
|
|
213
261
|
|
|
214
|
-
name =
|
|
262
|
+
name = local.gateway_waf_log_group_name
|
|
215
263
|
retention_in_days = 365
|
|
264
|
+
kms_key_id = aws_kms_key.gateway_waf_logs[0].arn
|
|
216
265
|
}
|
|
217
266
|
|
|
218
267
|
resource "aws_wafv2_web_acl_logging_configuration" "gateway_waf_logging" {
|
|
@@ -14,12 +14,6 @@ export declare const DEPENDENCIES: import("../utils/declared-dependencies.js").D
|
|
|
14
14
|
}, {
|
|
15
15
|
readonly name: "@types/express";
|
|
16
16
|
readonly dev: true;
|
|
17
|
-
}, {
|
|
18
|
-
readonly name: "ejs";
|
|
19
|
-
readonly dev: true;
|
|
20
|
-
}, {
|
|
21
|
-
readonly name: "@types/ejs";
|
|
22
|
-
readonly dev: true;
|
|
23
17
|
}, {
|
|
24
18
|
readonly name: "tsx";
|
|
25
19
|
readonly dev: true;
|
|
@@ -39,6 +33,13 @@ export declare const DEPENDENCIES: import("../utils/declared-dependencies.js").D
|
|
|
39
33
|
readonly when: (m: IacMetadata) => boolean;
|
|
40
34
|
} & {
|
|
41
35
|
versionOnly: true;
|
|
36
|
+
}, {
|
|
37
|
+
readonly name: "ejs";
|
|
38
|
+
readonly when: (m: IacMetadata) => boolean;
|
|
39
|
+
readonly dev: true;
|
|
40
|
+
readonly root: true;
|
|
41
|
+
} & {
|
|
42
|
+
versionOnly: true;
|
|
42
43
|
}, {
|
|
43
44
|
readonly name: "constructs";
|
|
44
45
|
readonly when: (m: IacMetadata) => boolean;
|
|
@@ -15,9 +15,8 @@ import { addGeneratorMetadata, getGeneratorInfo, projectExists, readProjectConfi
|
|
|
15
15
|
import { assignPort } from "../utils/port.js";
|
|
16
16
|
import { ensureProjectPackageJson } from "../utils/project-package-json.js";
|
|
17
17
|
import { SHARED_CONSTRUCTS_DEPENDENCIES, sharedConstructsGenerator } from "../utils/shared-constructs.js";
|
|
18
|
-
// The gateway's local-dev server
|
|
19
|
-
//
|
|
20
|
-
// gateway is a plain proxy).
|
|
18
|
+
// The gateway's local-dev server needs these whatever the auth; only the MCP
|
|
19
|
+
// SDK is protocol-specific (the http local gateway is a plain proxy).
|
|
21
20
|
export const DEPENDENCIES = declareDependencies()({
|
|
22
21
|
ts: [
|
|
23
22
|
{
|
|
@@ -31,15 +30,6 @@ export const DEPENDENCIES = declareDependencies()({
|
|
|
31
30
|
name: '@types/express',
|
|
32
31
|
dev: true
|
|
33
32
|
},
|
|
34
|
-
// ejs renders the Cedar policy in the shared gateway construct.
|
|
35
|
-
{
|
|
36
|
-
name: 'ejs',
|
|
37
|
-
dev: true
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
name: '@types/ejs',
|
|
41
|
-
dev: true
|
|
42
|
-
},
|
|
43
33
|
// local-dev.ts runs via tsx, which is shared tooling.
|
|
44
34
|
{
|
|
45
35
|
name: 'tsx',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx-plugin/src/agentcore-gateway/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addProjectConfiguration,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n logger,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addTsDependencies } from '../utils/add-dependencies.js';\nimport {\n AGENT_CORE_CONSTRUCTS_DEPENDENCIES,\n AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES,\n addAgentCoreGatewayInfra,\n} from '../utils/agent-core-constructs/agent-core-constructs.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../utils/declared-dependencies.js';\nimport { formatFilesInSubtree } from '../utils/format.js';\nimport { resolveIac } from '../utils/iac.js';\nimport { installDependencies } from '../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../utils/metrics.js';\nimport { kebabCase, toClassName } from '../utils/names.js';\nimport { getNpmScopePrefix } from '../utils/npm-scope.js';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n readProjectConfigurationUnqualified,\n} from '../utils/nx.js';\nimport { assignPort } from '../utils/port.js';\nimport { ensureProjectPackageJson } from '../utils/project-package-json.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../utils/shared-constructs.js';\nimport type { IacMetadata } from '../utils/shared-constructs-constants.js';\nimport type { AgentcoreGatewayGeneratorSchema } from './schema';\n\n// The gateway's local-dev server and Cedar policy rendering need these\n// whatever the auth; only the MCP SDK is protocol-specific (the http local\n// gateway is a plain proxy).\nexport const DEPENDENCIES = declareDependencies<AgentCoreGatewayMetadata>()({\n ts: [\n { name: '@modelcontextprotocol/sdk', when: (m) => m.protocol === 'mcp' },\n { name: 'express' },\n { name: '@types/express', dev: true },\n // ejs renders the Cedar policy in the shared gateway construct.\n { name: 'ejs', dev: true },\n { name: '@types/ejs', dev: true },\n // local-dev.ts runs via tsx, which is shared tooling.\n { name: 'tsx', dev: true, root: true },\n ...ownedElsewhere(AGENT_CORE_CONSTRUCTS_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: ownedElsewhere(AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES),\n});\n\nexport const AGENTCORE_GATEWAY_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const agentcoreGatewayGenerator = async (\n tree: Tree,\n options: AgentcoreGatewayGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const name = kebabCase(options.name);\n const nameClassName = toClassName(name);\n const parentDir = options.directory ?? 'packages';\n const subDir = options.subDirectory ?? name;\n const projectRoot = joinPathFragments(parentDir, subDir);\n const fullyQualifiedName = `${getNpmScopePrefix(tree)}${name}`;\n\n // Protocol is mcp (aggregate MCP server targets into one MCP endpoint) or\n // http (proxy agent runtime targets via path-based routing). Persisted in\n // metadata so connection generators can validate it.\n const protocol = options.protocol ?? 'mcp';\n // Inbound auth is iam (default) or cognito. Persisted in metadata so\n // connection generators can validate it (agent -> gateway connections\n // require an IAM gateway).\n const auth = options.auth ?? 'iam';\n // Cedar policies authorize MCP tool actions, which an http gateway has none\n // of — its runtime targets are plain proxied endpoints — so the policy\n // engine only applies to mcp gateways. cedarPolicy defaults to true in the\n // schema, so an http gateway quietly drops it rather than requiring\n // --cedarPolicy=false.\n if (protocol === 'http' && options.cedarPolicy) {\n logger.warn(\n 'Cedar policies authorize MCP tool actions, so cedarPolicy is ignored for http-protocol gateways.',\n );\n }\n const cedarPolicy = protocol === 'mcp' && (options.cedarPolicy ?? true);\n const infra = options.infra ?? 'agentcore';\n\n // local-dev.ts is the local gateway: a continuous MCP aggregator chaining\n // onto attached MCP servers' dev targets (added by the mcp-connection\n // generator), so a single `nx dev <gateway>` boots the gateway and every\n // attached MCP server together.\n //\n // `serve` exists for parity with other generators; the deployed Gateway is\n // a managed AWS resource, so `serve`-mode agents talk to it via runtime\n // config and the local gateway sits idle.\n const localGatewayTarget = (port: number) => ({\n executor: 'nx:run-commands' as const,\n continuous: true,\n options: {\n command: 'tsx local-dev.ts',\n cwd: '{projectRoot}',\n env: { PORT: `${port}` },\n },\n dependsOn: [] as Array<string | { projects: string[]; target: string }>,\n });\n let project: ProjectConfiguration;\n if (projectExists(tree, fullyQualifiedName)) {\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n } else {\n addProjectConfiguration(tree, fullyQualifiedName, {\n name: fullyQualifiedName,\n root: projectRoot,\n projectType: 'library',\n sourceRoot: projectRoot,\n tags: [],\n targets: {},\n metadata: {\n generator: AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n } as any,\n });\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n }\n // Ensure the project has its own package.json so its runtime dependencies\n // (added below) are declared in it rather than the workspace root.\n ensureProjectPackageJson(tree, {\n dir: projectRoot,\n fullyQualifiedName,\n });\n const port = assignPort(tree, project, 8100);\n // A gateway is its own standalone project, so it uses plain `serve` / `dev`\n // targets. Re-run: keep existing targets (their dependsOn may have been\n // populated by the mcp-connection generator), just ensure both exist.\n project.targets ??= {};\n project.targets['serve'] ??= localGatewayTarget(port);\n project.targets['dev'] ??= localGatewayTarget(port);\n updateProjectConfiguration(tree, project.name, project);\n\n // Scaffold the gateway project: local-dev.ts (+ Cedar policies if requested)\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'project', protocol),\n projectRoot,\n {\n nameClassName,\n nameKebabCase: name,\n port,\n attachedMcpServers: [],\n attachedAgents: [],\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n if (cedarPolicy) {\n // The default permit-all policy differs by auth type: AgentCore represents\n // IAM callers as `AgentCore::IamEntity` and Cognito/JWT callers as\n // `AgentCore::OAuthUser`, so the two policies match different principals.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cedar'),\n projectRoot,\n { nameClassName, auth },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n }\n\n // Recorded in the metadata below so the version sync can tell a CDK\n // project from a Terraform one; undefined when no infrastructure was\n // generated, in which case neither provider's packages were added.\n const iac =\n infra !== 'none' ? await resolveIac(tree, options.iac) : undefined;\n\n // Recorded below and read by the declaration's predicates, so the packages\n // added here are exactly the ones the version sync will own.\n const metadata: AgentCoreGatewayMetadata = {\n name,\n rc: nameClassName,\n protocol,\n auth,\n port,\n ...(iac ? { iac } : {}),\n };\n\n addGeneratorMetadata(\n tree,\n fullyQualifiedName,\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n metadata,\n );\n\n addTsDependencies(tree, DEPENDENCIES, { metadata, projectRoot });\n\n // Wire up infra (CDK or Terraform); re-running with infra=agentcore adds\n // the infrastructure to a previously infra-less gateway.\n\n if (infra === 'agentcore') {\n await sharedConstructsGenerator(tree, { iac }, DEPENDENCIES);\n\n await addAgentCoreGatewayInfra(\n tree,\n {\n gatewayNameClassName: nameClassName,\n gatewayNameKebabCase: name,\n projectName: fullyQualifiedName,\n projectDirectory: projectRoot,\n cedarPolicy,\n auth,\n protocol,\n iac,\n },\n DEPENDENCIES,\n );\n }\n\n await addGeneratorMetricsIfApplicable(tree, [\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n ]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\n/**\n * Gateway details stored in the gateway project's metadata.\n */\nexport interface AgentCoreGatewayMetadata extends IacMetadata {\n name: string;\n rc: string;\n protocol: string;\n auth: string;\n port: number;\n}\n\n/**\n * Read a gateway project's metadata, validating it was generated by the\n * agentcore-gateway generator.\n */\nexport const readAgentCoreGatewayMetadata = (\n project: ProjectConfiguration,\n): AgentCoreGatewayMetadata => {\n const metadata = project.metadata as any;\n if (metadata?.generator !== AGENTCORE_GATEWAY_GENERATOR_INFO.id) {\n throw new Error(\n `Project '${project.name}' was not generated by the '${AGENTCORE_GATEWAY_GENERATOR_INFO.id}' generator.`,\n );\n }\n return metadata as AgentCoreGatewayMetadata;\n};\n\nexport default agentcoreGatewayGenerator;\n"],"names":["addProjectConfiguration","generateFiles","joinPathFragments","logger","OverwriteStrategy","updateProjectConfiguration","addTsDependencies","AGENT_CORE_CONSTRUCTS_DEPENDENCIES","AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES","addAgentCoreGatewayInfra","declareDependencies","ownedElsewhere","formatFilesInSubtree","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","getNpmScopePrefix","addGeneratorMetadata","getGeneratorInfo","projectExists","readProjectConfigurationUnqualified","assignPort","ensureProjectPackageJson","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","DEPENDENCIES","ts","name","when","m","protocol","dev","root","py","AGENTCORE_GATEWAY_GENERATOR_INFO","filename","agentcoreGatewayGenerator","tree","options","nameClassName","parentDir","directory","subDir","subDirectory","projectRoot","fullyQualifiedName","auth","cedarPolicy","warn","infra","localGatewayTarget","port","executor","continuous","command","cwd","env","PORT","dependsOn","project","projectType","sourceRoot","tags","targets","metadata","generator","id","dir","dirname","nameKebabCase","attachedMcpServers","attachedAgents","overwriteStrategy","KeepExisting","iac","undefined","rc","gatewayNameClassName","gatewayNameKebabCase","projectName","projectDirectory","preferInstallDependencies","languages","readAgentCoreGatewayMetadata","Error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx-plugin/src/agentcore-gateway/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addProjectConfiguration,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n logger,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addTsDependencies } from '../utils/add-dependencies.js';\nimport {\n AGENT_CORE_CONSTRUCTS_DEPENDENCIES,\n AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES,\n addAgentCoreGatewayInfra,\n} from '../utils/agent-core-constructs/agent-core-constructs.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../utils/declared-dependencies.js';\nimport { formatFilesInSubtree } from '../utils/format.js';\nimport { resolveIac } from '../utils/iac.js';\nimport { installDependencies } from '../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../utils/metrics.js';\nimport { kebabCase, toClassName } from '../utils/names.js';\nimport { getNpmScopePrefix } from '../utils/npm-scope.js';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n readProjectConfigurationUnqualified,\n} from '../utils/nx.js';\nimport { assignPort } from '../utils/port.js';\nimport { ensureProjectPackageJson } from '../utils/project-package-json.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../utils/shared-constructs.js';\nimport type { IacMetadata } from '../utils/shared-constructs-constants.js';\nimport type { AgentcoreGatewayGeneratorSchema } from './schema';\n\n// The gateway's local-dev server needs these whatever the auth; only the MCP\n// SDK is protocol-specific (the http local gateway is a plain proxy).\nexport const DEPENDENCIES = declareDependencies<AgentCoreGatewayMetadata>()({\n ts: [\n { name: '@modelcontextprotocol/sdk', when: (m) => m.protocol === 'mcp' },\n { name: 'express' },\n { name: '@types/express', dev: true },\n // local-dev.ts runs via tsx, which is shared tooling.\n { name: 'tsx', dev: true, root: true },\n ...ownedElsewhere(AGENT_CORE_CONSTRUCTS_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: ownedElsewhere(AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES),\n});\n\nexport const AGENTCORE_GATEWAY_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const agentcoreGatewayGenerator = async (\n tree: Tree,\n options: AgentcoreGatewayGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const name = kebabCase(options.name);\n const nameClassName = toClassName(name);\n const parentDir = options.directory ?? 'packages';\n const subDir = options.subDirectory ?? name;\n const projectRoot = joinPathFragments(parentDir, subDir);\n const fullyQualifiedName = `${getNpmScopePrefix(tree)}${name}`;\n\n // Protocol is mcp (aggregate MCP server targets into one MCP endpoint) or\n // http (proxy agent runtime targets via path-based routing). Persisted in\n // metadata so connection generators can validate it.\n const protocol = options.protocol ?? 'mcp';\n // Inbound auth is iam (default) or cognito. Persisted in metadata so\n // connection generators can validate it (agent -> gateway connections\n // require an IAM gateway).\n const auth = options.auth ?? 'iam';\n // Cedar policies authorize MCP tool actions, which an http gateway has none\n // of — its runtime targets are plain proxied endpoints — so the policy\n // engine only applies to mcp gateways. cedarPolicy defaults to true in the\n // schema, so an http gateway quietly drops it rather than requiring\n // --cedarPolicy=false.\n if (protocol === 'http' && options.cedarPolicy) {\n logger.warn(\n 'Cedar policies authorize MCP tool actions, so cedarPolicy is ignored for http-protocol gateways.',\n );\n }\n const cedarPolicy = protocol === 'mcp' && (options.cedarPolicy ?? true);\n const infra = options.infra ?? 'agentcore';\n\n // local-dev.ts is the local gateway: a continuous MCP aggregator chaining\n // onto attached MCP servers' dev targets (added by the mcp-connection\n // generator), so a single `nx dev <gateway>` boots the gateway and every\n // attached MCP server together.\n //\n // `serve` exists for parity with other generators; the deployed Gateway is\n // a managed AWS resource, so `serve`-mode agents talk to it via runtime\n // config and the local gateway sits idle.\n const localGatewayTarget = (port: number) => ({\n executor: 'nx:run-commands' as const,\n continuous: true,\n options: {\n command: 'tsx local-dev.ts',\n cwd: '{projectRoot}',\n env: { PORT: `${port}` },\n },\n dependsOn: [] as Array<string | { projects: string[]; target: string }>,\n });\n let project: ProjectConfiguration;\n if (projectExists(tree, fullyQualifiedName)) {\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n } else {\n addProjectConfiguration(tree, fullyQualifiedName, {\n name: fullyQualifiedName,\n root: projectRoot,\n projectType: 'library',\n sourceRoot: projectRoot,\n tags: [],\n targets: {},\n metadata: {\n generator: AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n } as any,\n });\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n }\n // Ensure the project has its own package.json so its runtime dependencies\n // (added below) are declared in it rather than the workspace root.\n ensureProjectPackageJson(tree, {\n dir: projectRoot,\n fullyQualifiedName,\n });\n const port = assignPort(tree, project, 8100);\n // A gateway is its own standalone project, so it uses plain `serve` / `dev`\n // targets. Re-run: keep existing targets (their dependsOn may have been\n // populated by the mcp-connection generator), just ensure both exist.\n project.targets ??= {};\n project.targets['serve'] ??= localGatewayTarget(port);\n project.targets['dev'] ??= localGatewayTarget(port);\n updateProjectConfiguration(tree, project.name, project);\n\n // Scaffold the gateway project: local-dev.ts (+ Cedar policies if requested)\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'project', protocol),\n projectRoot,\n {\n nameClassName,\n nameKebabCase: name,\n port,\n attachedMcpServers: [],\n attachedAgents: [],\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n if (cedarPolicy) {\n // The default permit-all policy differs by auth type: AgentCore represents\n // IAM callers as `AgentCore::IamEntity` and Cognito/JWT callers as\n // `AgentCore::OAuthUser`, so the two policies match different principals.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cedar'),\n projectRoot,\n { nameClassName, auth },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n }\n\n // Recorded in the metadata below so the version sync can tell a CDK\n // project from a Terraform one; undefined when no infrastructure was\n // generated, in which case neither provider's packages were added.\n const iac =\n infra !== 'none' ? await resolveIac(tree, options.iac) : undefined;\n\n // Recorded below and read by the declaration's predicates, so the packages\n // added here are exactly the ones the version sync will own.\n const metadata: AgentCoreGatewayMetadata = {\n name,\n rc: nameClassName,\n protocol,\n auth,\n port,\n ...(iac ? { iac } : {}),\n };\n\n addGeneratorMetadata(\n tree,\n fullyQualifiedName,\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n metadata,\n );\n\n addTsDependencies(tree, DEPENDENCIES, { metadata, projectRoot });\n\n // Wire up infra (CDK or Terraform); re-running with infra=agentcore adds\n // the infrastructure to a previously infra-less gateway.\n\n if (infra === 'agentcore') {\n await sharedConstructsGenerator(tree, { iac }, DEPENDENCIES);\n\n await addAgentCoreGatewayInfra(\n tree,\n {\n gatewayNameClassName: nameClassName,\n gatewayNameKebabCase: name,\n projectName: fullyQualifiedName,\n projectDirectory: projectRoot,\n cedarPolicy,\n auth,\n protocol,\n iac,\n },\n DEPENDENCIES,\n );\n }\n\n await addGeneratorMetricsIfApplicable(tree, [\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n ]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\n/**\n * Gateway details stored in the gateway project's metadata.\n */\nexport interface AgentCoreGatewayMetadata extends IacMetadata {\n name: string;\n rc: string;\n protocol: string;\n auth: string;\n port: number;\n}\n\n/**\n * Read a gateway project's metadata, validating it was generated by the\n * agentcore-gateway generator.\n */\nexport const readAgentCoreGatewayMetadata = (\n project: ProjectConfiguration,\n): AgentCoreGatewayMetadata => {\n const metadata = project.metadata as any;\n if (metadata?.generator !== AGENTCORE_GATEWAY_GENERATOR_INFO.id) {\n throw new Error(\n `Project '${project.name}' was not generated by the '${AGENTCORE_GATEWAY_GENERATOR_INFO.id}' generator.`,\n );\n }\n return metadata as AgentCoreGatewayMetadata;\n};\n\nexport default agentcoreGatewayGenerator;\n"],"names":["addProjectConfiguration","generateFiles","joinPathFragments","logger","OverwriteStrategy","updateProjectConfiguration","addTsDependencies","AGENT_CORE_CONSTRUCTS_DEPENDENCIES","AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES","addAgentCoreGatewayInfra","declareDependencies","ownedElsewhere","formatFilesInSubtree","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","getNpmScopePrefix","addGeneratorMetadata","getGeneratorInfo","projectExists","readProjectConfigurationUnqualified","assignPort","ensureProjectPackageJson","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","DEPENDENCIES","ts","name","when","m","protocol","dev","root","py","AGENTCORE_GATEWAY_GENERATOR_INFO","filename","agentcoreGatewayGenerator","tree","options","nameClassName","parentDir","directory","subDir","subDirectory","projectRoot","fullyQualifiedName","auth","cedarPolicy","warn","infra","localGatewayTarget","port","executor","continuous","command","cwd","env","PORT","dependsOn","project","projectType","sourceRoot","tags","targets","metadata","generator","id","dir","dirname","nameKebabCase","attachedMcpServers","attachedAgents","overwriteStrategy","KeepExisting","iac","undefined","rc","gatewayNameClassName","gatewayNameKebabCase","projectName","projectDirectory","preferInstallDependencies","languages","readAgentCoreGatewayMetadata","Error"],"mappings":"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"}
|
|
@@ -62,14 +62,13 @@ construct's \`grantInvokeAccess\` grants exactly those two actions.
|
|
|
62
62
|
## Customizing your Harness
|
|
63
63
|
|
|
64
64
|
Edit \`src/PROMPT.md\` for the system prompt. Everything else is configured
|
|
65
|
-
where you instantiate the infrastructure — including tools, which
|
|
66
|
-
|
|
65
|
+
where you instantiate the infrastructure — including tools, which default
|
|
66
|
+
to none:
|
|
67
67
|
|
|
68
68
|
- CDK construct props, for example
|
|
69
69
|
\`new MyHarness(this, 'MyHarness', { allowedTools: ['@builtin'] })\`
|
|
70
|
-
- Terraform, by setting
|
|
71
|
-
\`
|
|
72
|
-
variable if you would rather set it as a module argument
|
|
70
|
+
- Terraform, by setting the module's \`allowed_tools\` variable, for example
|
|
71
|
+
\`allowed_tools = ["@builtin"]\`
|
|
73
72
|
|
|
74
73
|
The generated infrastructure is also yours to edit directly:
|
|
75
74
|
|
|
@@ -59,14 +59,13 @@ construct's `grantInvokeAccess` grants exactly those two actions.
|
|
|
59
59
|
## Customizing your Harness
|
|
60
60
|
|
|
61
61
|
Edit `src/PROMPT.md` for the system prompt. Everything else is configured
|
|
62
|
-
where you instantiate the infrastructure — including tools, which
|
|
63
|
-
|
|
62
|
+
where you instantiate the infrastructure — including tools, which default
|
|
63
|
+
to none:
|
|
64
64
|
|
|
65
65
|
- CDK construct props, for example
|
|
66
66
|
`new <%- nameClassName %>(this, '<%- nameClassName %>', { allowedTools: ['@builtin'] })`
|
|
67
|
-
- Terraform, by setting
|
|
68
|
-
`
|
|
69
|
-
variable if you would rather set it as a module argument
|
|
67
|
+
- Terraform, by setting the module's `allowed_tools` variable, for example
|
|
68
|
+
`allowed_tools = ["@builtin"]`
|
|
70
69
|
|
|
71
70
|
The generated infrastructure is also yours to edit directly:
|
|
72
71
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`agentcore-harness-no-tools-by-default migration > cdk > defaults allowedTools to none and passes it explicitly 1`] = `
|
|
4
|
+
"import * as agentcore from 'aws-cdk-lib/aws-bedrockagentcore';
|
|
5
|
+
import { Construct } from 'constructs';
|
|
6
|
+
|
|
7
|
+
export class MyHarness extends Construct {
|
|
8
|
+
public readonly harness: agentcore.CfnHarness;
|
|
9
|
+
|
|
10
|
+
constructor(scope: Construct, id: string, props?: MyHarnessProps) {
|
|
11
|
+
super(scope, id);
|
|
12
|
+
|
|
13
|
+
const stack = Stack.of(this);
|
|
14
|
+
const {
|
|
15
|
+
// The service treats an absent allowedTools as every tool, so this
|
|
16
|
+
// defaults to none and is always passed explicitly.
|
|
17
|
+
allowedTools = [],
|
|
18
|
+
executionRole,
|
|
19
|
+
modelResourceArns = [
|
|
20
|
+
\`arn:\${stack.partition}:bedrock:*::foundation-model/*\`,
|
|
21
|
+
],
|
|
22
|
+
vpc,
|
|
23
|
+
vpcSubnets,
|
|
24
|
+
securityGroups,
|
|
25
|
+
...harnessProps
|
|
26
|
+
} = props ?? {};
|
|
27
|
+
|
|
28
|
+
this.harness = new agentcore.CfnHarness(this, 'Harness', {
|
|
29
|
+
model: {
|
|
30
|
+
bedrockModelConfig: {
|
|
31
|
+
modelId: 'global.anthropic.claude-sonnet-4-6',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
systemPrompt: [{ text: systemPrompt }],
|
|
35
|
+
...harnessProps,
|
|
36
|
+
allowedTools,
|
|
37
|
+
// Set after harnessProps so the deployed name always matches the
|
|
38
|
+
// execution role's workload-identity resource pattern.
|
|
39
|
+
harnessName,
|
|
40
|
+
executionRoleArn: this.executionRole.roleArn,
|
|
41
|
+
environment,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
"
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
exports[`agentcore-harness-no-tools-by-default migration > terraform > declares allowed_tools defaulting to none and assigns it 1`] = `
|
|
49
|
+
"variable "model_id" {
|
|
50
|
+
description = "Amazon Bedrock model or inference profile used by default."
|
|
51
|
+
type = string
|
|
52
|
+
default = "global.anthropic.claude-sonnet-4-6"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
variable "allowed_tools" {
|
|
56
|
+
description = "Tools the Harness may use. Defaults to none; set [\\"@builtin\\"] for every built-in tool, or name individual tools. Always sent explicitly, since the service treats an absent value as every tool."
|
|
57
|
+
type = list(string)
|
|
58
|
+
default = []
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
variable "model_resource_arns" {
|
|
62
|
+
description = "Bedrock model and inference-profile ARNs the execution role may invoke."
|
|
63
|
+
type = set(string)
|
|
64
|
+
default = null
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
resource "aws_bedrockagentcore_harness" "this" {
|
|
68
|
+
harness_name = local.harness_name
|
|
69
|
+
execution_role_arn = aws_iam_role.execution_role.arn
|
|
70
|
+
allowed_tools = var.allowed_tools
|
|
71
|
+
|
|
72
|
+
model {
|
|
73
|
+
bedrock_model_config {
|
|
74
|
+
model_id = var.model_id
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
"
|
|
79
|
+
`;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type MigrationReturnObject, type Tree } from '@nx/devkit';
|
|
6
|
+
export default function migration(tree: Tree): Promise<MigrationReturnObject>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { joinPathFragments } from "@nx/devkit";
|
|
5
|
+
import { applyGritQL, GRIT_INSERT_PLACEHOLDER, insertViaGritQL, matchGritQL } from "../../../utils/ast.js";
|
|
6
|
+
import { formatFilesInSubtree } from "../../../utils/format.js";
|
|
7
|
+
import { PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, SHARED_TERRAFORM_DIR } from "../../../utils/shared-constructs-constants.js";
|
|
8
|
+
/**
|
|
9
|
+
* Pin each vended Harness to no tools by default.
|
|
10
|
+
*
|
|
11
|
+
* AgentCore treats an absent `allowedTools` as every tool, so a Harness that
|
|
12
|
+
* never set it deployed with `allowedTools: ["*"]` — shell execution and file
|
|
13
|
+
* read/write included. Both providers now send the field explicitly, defaulting
|
|
14
|
+
* to none.
|
|
15
|
+
*
|
|
16
|
+
* These files are generated with `KeepExisting`, so an upgraded workspace keeps
|
|
17
|
+
* the implicit every-tool default until this runs. Diverged files are left
|
|
18
|
+
* untouched and reported via `nextSteps`.
|
|
19
|
+
*/ const CDK_HARNESSES_DIR = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/app/harnesses`;
|
|
20
|
+
const TERRAFORM_HARNESSES_DIR = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/app/harnesses`;
|
|
21
|
+
const hcl = (pattern)=>`language hcl\n${pattern}`;
|
|
22
|
+
const ALLOWED_TOOLS_VARIABLE = [
|
|
23
|
+
'variable "allowed_tools" {',
|
|
24
|
+
' description = "Tools the Harness may use. Defaults to none; set [\\"@builtin\\"] for every built-in tool, or name individual tools. Always sent explicitly, since the service treats an absent value as every tool."',
|
|
25
|
+
' type = list(string)',
|
|
26
|
+
' default = []',
|
|
27
|
+
'}'
|
|
28
|
+
].join('\n');
|
|
29
|
+
const divergedMessage = (filePath, remedy)=>`${filePath}: has diverged from the generated shape - left untouched. AgentCore treats an absent allowedTools as every tool, so this Harness deploys with all built-in tools (including shell and file access). ${remedy}`;
|
|
30
|
+
/**
|
|
31
|
+
* Default the construct's `allowedTools` to none and pass it to the resource
|
|
32
|
+
* after the props spread, so an undefined caller value cannot reinstate the
|
|
33
|
+
* service's every-tool default.
|
|
34
|
+
*/ const migrateCdkConstruct = async (tree, filePath)=>{
|
|
35
|
+
const destructured = await insertViaGritQL(tree, filePath, `\`const { $fields } = props ?? {};\` => \`const {\n ${GRIT_INSERT_PLACEHOLDER}\n $fields\n } = props ?? {};\``, [
|
|
36
|
+
'// The service treats an absent allowedTools as every tool, so this',
|
|
37
|
+
'// defaults to none and is always passed explicitly.',
|
|
38
|
+
'allowedTools = [],'
|
|
39
|
+
].join('\n '));
|
|
40
|
+
if (!destructured) return false;
|
|
41
|
+
return await applyGritQL(tree, filePath, '`new agentcore.CfnHarness($scope, $id, { $props })` where {' + ' $props <: contains spread_element() as $spread,' + ' $spread => `$spread,\n allowedTools`' + ' }');
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Declare `allowed_tools` and assign it to the Harness resource, so the module
|
|
45
|
+
* always sends the field.
|
|
46
|
+
*/ const migrateTerraformModule = async (tree, filePath)=>{
|
|
47
|
+
const declared = await insertViaGritQL(tree, filePath, hcl(`\`variable "model_resource_arns" { $props }\` => \`${GRIT_INSERT_PLACEHOLDER}\n\nvariable "model_resource_arns" {\n $props\n}\``), ALLOWED_TOOLS_VARIABLE);
|
|
48
|
+
if (!declared) return false;
|
|
49
|
+
// Appended after the existing arguments so their alignment is preserved;
|
|
50
|
+
// `terraform fmt` re-aligns the block.
|
|
51
|
+
return await applyGritQL(tree, filePath, hcl('`execution_role_arn = aws_iam_role.execution_role.arn` => `execution_role_arn = aws_iam_role.execution_role.arn\n allowed_tools = var.allowed_tools`'));
|
|
52
|
+
};
|
|
53
|
+
export default async function migration(tree) {
|
|
54
|
+
const nextSteps = [];
|
|
55
|
+
for (const dirName of tree.exists(CDK_HARNESSES_DIR) ? tree.children(CDK_HARNESSES_DIR) : []){
|
|
56
|
+
const filePath = joinPathFragments(CDK_HARNESSES_DIR, dirName, `${dirName}.ts`);
|
|
57
|
+
if (!tree.exists(filePath)) {
|
|
58
|
+
continue; // Not a Harness construct directory.
|
|
59
|
+
}
|
|
60
|
+
// Already pinned, by this migration or by hand.
|
|
61
|
+
if (tree.read(filePath, 'utf-8')?.includes('allowedTools = [],')) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (!await migrateCdkConstruct(tree, filePath)) {
|
|
65
|
+
nextSteps.push(divergedMessage(filePath, 'Default `allowedTools` to `[]` when destructuring props, and pass `allowedTools` to the CfnHarness after the `...harnessProps` spread.'));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (const dirName of tree.exists(TERRAFORM_HARNESSES_DIR) ? tree.children(TERRAFORM_HARNESSES_DIR) : []){
|
|
69
|
+
const filePath = joinPathFragments(TERRAFORM_HARNESSES_DIR, dirName, `${dirName}.tf`);
|
|
70
|
+
if (!tree.exists(filePath)) {
|
|
71
|
+
continue; // Not a Harness module directory.
|
|
72
|
+
}
|
|
73
|
+
// Already assigned, by this migration or by hand.
|
|
74
|
+
if (await matchGritQL(tree, filePath, hcl('`allowed_tools = $_`'))) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (!await migrateTerraformModule(tree, filePath)) {
|
|
78
|
+
nextSteps.push(divergedMessage(filePath, 'Declare an `allowed_tools` variable (list(string), default []) and assign `allowed_tools = var.allowed_tools` on the `aws_bedrockagentcore_harness` resource.'));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
await formatFilesInSubtree(tree);
|
|
82
|
+
return {
|
|
83
|
+
nextSteps
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/agentcore-harness-no-tools-by-default/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport {\n applyGritQL,\n GRIT_INSERT_PLACEHOLDER,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Pin each vended Harness to no tools by default.\n *\n * AgentCore treats an absent `allowedTools` as every tool, so a Harness that\n * never set it deployed with `allowedTools: [\"*\"]` — shell execution and file\n * read/write included. Both providers now send the field explicitly, defaulting\n * to none.\n *\n * These files are generated with `KeepExisting`, so an upgraded workspace keeps\n * the implicit every-tool default until this runs. Diverged files are left\n * untouched and reported via `nextSteps`.\n */\n\nconst CDK_HARNESSES_DIR = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/app/harnesses`;\nconst TERRAFORM_HARNESSES_DIR = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/app/harnesses`;\n\nconst hcl = (pattern: string) => `language hcl\\n${pattern}`;\n\nconst ALLOWED_TOOLS_VARIABLE = [\n 'variable \"allowed_tools\" {',\n ' description = \"Tools the Harness may use. Defaults to none; set [\\\\\"@builtin\\\\\"] for every built-in tool, or name individual tools. Always sent explicitly, since the service treats an absent value as every tool.\"',\n ' type = list(string)',\n ' default = []',\n '}',\n].join('\\n');\n\nconst divergedMessage = (filePath: string, remedy: string) =>\n `${filePath}: has diverged from the generated shape - left untouched. AgentCore treats an absent allowedTools as every tool, so this Harness deploys with all built-in tools (including shell and file access). ${remedy}`;\n\n/**\n * Default the construct's `allowedTools` to none and pass it to the resource\n * after the props spread, so an undefined caller value cannot reinstate the\n * service's every-tool default.\n */\nconst migrateCdkConstruct = async (\n tree: Tree,\n filePath: string,\n): Promise<boolean> => {\n const destructured = await insertViaGritQL(\n tree,\n filePath,\n `\\`const { $fields } = props ?? {};\\` => \\`const {\\n ${GRIT_INSERT_PLACEHOLDER}\\n $fields\\n } = props ?? {};\\``,\n [\n '// The service treats an absent allowedTools as every tool, so this',\n '// defaults to none and is always passed explicitly.',\n 'allowedTools = [],',\n ].join('\\n '),\n );\n if (!destructured) return false;\n\n return await applyGritQL(\n tree,\n filePath,\n '`new agentcore.CfnHarness($scope, $id, { $props })` where {' +\n ' $props <: contains spread_element() as $spread,' +\n ' $spread => `$spread,\\n allowedTools`' +\n ' }',\n );\n};\n\n/**\n * Declare `allowed_tools` and assign it to the Harness resource, so the module\n * always sends the field.\n */\nconst migrateTerraformModule = async (\n tree: Tree,\n filePath: string,\n): Promise<boolean> => {\n const declared = await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`variable \"model_resource_arns\" { $props }\\` => \\`${GRIT_INSERT_PLACEHOLDER}\\n\\nvariable \"model_resource_arns\" {\\n $props\\n}\\``,\n ),\n ALLOWED_TOOLS_VARIABLE,\n );\n if (!declared) return false;\n\n // Appended after the existing arguments so their alignment is preserved;\n // `terraform fmt` re-aligns the block.\n return await applyGritQL(\n tree,\n filePath,\n hcl(\n '`execution_role_arn = aws_iam_role.execution_role.arn` => `execution_role_arn = aws_iam_role.execution_role.arn\\n allowed_tools = var.allowed_tools`',\n ),\n );\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n for (const dirName of tree.exists(CDK_HARNESSES_DIR)\n ? tree.children(CDK_HARNESSES_DIR)\n : []) {\n const filePath = joinPathFragments(\n CDK_HARNESSES_DIR,\n dirName,\n `${dirName}.ts`,\n );\n if (!tree.exists(filePath)) {\n continue; // Not a Harness construct directory.\n }\n\n // Already pinned, by this migration or by hand.\n if (tree.read(filePath, 'utf-8')?.includes('allowedTools = [],')) {\n continue;\n }\n\n if (!(await migrateCdkConstruct(tree, filePath))) {\n nextSteps.push(\n divergedMessage(\n filePath,\n 'Default `allowedTools` to `[]` when destructuring props, and pass `allowedTools` to the CfnHarness after the `...harnessProps` spread.',\n ),\n );\n }\n }\n\n for (const dirName of tree.exists(TERRAFORM_HARNESSES_DIR)\n ? tree.children(TERRAFORM_HARNESSES_DIR)\n : []) {\n const filePath = joinPathFragments(\n TERRAFORM_HARNESSES_DIR,\n dirName,\n `${dirName}.tf`,\n );\n if (!tree.exists(filePath)) {\n continue; // Not a Harness module directory.\n }\n\n // Already assigned, by this migration or by hand.\n if (await matchGritQL(tree, filePath, hcl('`allowed_tools = $_`'))) {\n continue;\n }\n\n if (!(await migrateTerraformModule(tree, filePath))) {\n nextSteps.push(\n divergedMessage(\n filePath,\n 'Declare an `allowed_tools` variable (list(string), default []) and assign `allowed_tools = var.allowed_tools` on the `aws_bedrockagentcore_harness` resource.',\n ),\n );\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["joinPathFragments","applyGritQL","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","CDK_HARNESSES_DIR","TERRAFORM_HARNESSES_DIR","hcl","pattern","ALLOWED_TOOLS_VARIABLE","join","divergedMessage","filePath","remedy","migrateCdkConstruct","tree","destructured","migrateTerraformModule","declared","migration","nextSteps","dirName","exists","children","read","includes","push"],"mappings":"AAAA;;;CAGC,GACD,SACEA,iBAAiB,QAGZ,aAAa;AACpB,SACEC,WAAW,EACXC,uBAAuB,EACvBC,eAAe,EACfC,WAAW,QACN,wBAAwB;AAC/B,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SACEC,YAAY,EACZC,qBAAqB,EACrBC,oBAAoB,QACf,gDAAgD;AAEvD;;;;;;;;;;;CAWC,GAED,MAAMC,oBAAoB,GAAGH,aAAa,CAAC,EAAEC,sBAAsB,kBAAkB,CAAC;AACtF,MAAMG,0BAA0B,GAAGJ,aAAa,CAAC,EAAEE,qBAAqB,kBAAkB,CAAC;AAE3F,MAAMG,MAAM,CAACC,UAAoB,CAAC,cAAc,EAAEA,SAAS;AAE3D,MAAMC,yBAAyB;IAC7B;IACA;IACA;IACA;IACA;CACD,CAACC,IAAI,CAAC;AAEP,MAAMC,kBAAkB,CAACC,UAAkBC,SACzC,GAAGD,SAAS,oMAAoM,EAAEC,QAAQ;AAE5N;;;;CAIC,GACD,MAAMC,sBAAsB,OAC1BC,MACAH;IAEA,MAAMI,eAAe,MAAMjB,gBACzBgB,MACAH,UACA,CAAC,yDAAyD,EAAEd,wBAAwB,uCAAuC,CAAC,EAC5H;QACE;QACA;QACA;KACD,CAACY,IAAI,CAAC;IAET,IAAI,CAACM,cAAc,OAAO;IAE1B,OAAO,MAAMnB,YACXkB,MACAH,UACA,gEACE,qDACA,+CACA;AAEN;AAEA;;;CAGC,GACD,MAAMK,yBAAyB,OAC7BF,MACAH;IAEA,MAAMM,WAAW,MAAMnB,gBACrBgB,MACAH,UACAL,IACE,CAAC,mDAAmD,EAAET,wBAAwB,mDAAmD,CAAC,GAEpIW;IAEF,IAAI,CAACS,UAAU,OAAO;IAEtB,yEAAyE;IACzE,uCAAuC;IACvC,OAAO,MAAMrB,YACXkB,MACAH,UACAL,IACE;AAGN;AAEA,eAAe,eAAeY,UAC5BJ,IAAU;IAEV,MAAMK,YAAsB,EAAE;IAE9B,KAAK,MAAMC,WAAWN,KAAKO,MAAM,CAACjB,qBAC9BU,KAAKQ,QAAQ,CAAClB,qBACd,EAAE,CAAE;QACN,MAAMO,WAAWhB,kBACfS,mBACAgB,SACA,GAAGA,QAAQ,GAAG,CAAC;QAEjB,IAAI,CAACN,KAAKO,MAAM,CAACV,WAAW;YAC1B,UAAU,qCAAqC;QACjD;QAEA,gDAAgD;QAChD,IAAIG,KAAKS,IAAI,CAACZ,UAAU,UAAUa,SAAS,uBAAuB;YAChE;QACF;QAEA,IAAI,CAAE,MAAMX,oBAAoBC,MAAMH,WAAY;YAChDQ,UAAUM,IAAI,CACZf,gBACEC,UACA;QAGN;IACF;IAEA,KAAK,MAAMS,WAAWN,KAAKO,MAAM,CAAChB,2BAC9BS,KAAKQ,QAAQ,CAACjB,2BACd,EAAE,CAAE;QACN,MAAMM,WAAWhB,kBACfU,yBACAe,SACA,GAAGA,QAAQ,GAAG,CAAC;QAEjB,IAAI,CAACN,KAAKO,MAAM,CAACV,WAAW;YAC1B,UAAU,kCAAkC;QAC9C;QAEA,kDAAkD;QAClD,IAAI,MAAMZ,YAAYe,MAAMH,UAAUL,IAAI,0BAA0B;YAClE;QACF;QAEA,IAAI,CAAE,MAAMU,uBAAuBF,MAAMH,WAAY;YACnDQ,UAAUM,IAAI,CACZf,gBACEC,UACA;QAGN;IACF;IAEA,MAAMX,qBAAqBc;IAE3B,OAAO;QAAEK;IAAU;AACrB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type MigrationReturnObject, type Tree } from '@nx/devkit';
|
|
6
|
+
export default function migration(tree: Tree): Promise<MigrationReturnObject>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { joinPathFragments } from "@nx/devkit";
|
|
5
|
+
import { GRIT_INSERT_PLACEHOLDER, insertViaGritQL, matchGritQL } from "../../../utils/ast.js";
|
|
6
|
+
import { formatFilesInSubtree } from "../../../utils/format.js";
|
|
7
|
+
import { PACKAGES_DIR, SHARED_TERRAFORM_DIR } from "../../../utils/shared-constructs-constants.js";
|
|
8
|
+
/**
|
|
9
|
+
* Re-export the core dynamodb module's `table_name`, `table_arn` and
|
|
10
|
+
* `kms_key_arn` from each vended per-table Terraform app module
|
|
11
|
+
* (`app/dynamodb/<name>/<name>.tf`).
|
|
12
|
+
*
|
|
13
|
+
* The app module is what a root configuration instantiates, so without these
|
|
14
|
+
* outputs a root module cannot reference the table or its encryption key at
|
|
15
|
+
* all — for example to grant a consumer access to it.
|
|
16
|
+
*
|
|
17
|
+
* These files are generated with `KeepExisting`, so an upgraded workspace keeps
|
|
18
|
+
* a module with no outputs until this runs. Diverged files are left untouched
|
|
19
|
+
* and reported via `nextSteps`.
|
|
20
|
+
*/ const TERRAFORM_DYNAMODB_APP_DIR = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/app/dynamodb`;
|
|
21
|
+
const divergedMessage = (filePath)=>`${filePath}: has diverged from the generated shape - left untouched. To reference the table from your root Terraform configuration, add table_name, table_arn and kms_key_arn outputs here forwarding the equivalent module.dynamodb_table attributes (see the ts#dynamodb generator's dynamodb app template).`;
|
|
22
|
+
const hcl = (pattern)=>`language hcl\n${pattern}`;
|
|
23
|
+
const OUTPUTS_TEXT = [
|
|
24
|
+
'output "table_name" {',
|
|
25
|
+
' description = "Name of the DynamoDB table"',
|
|
26
|
+
' value = module.dynamodb_table.table_name',
|
|
27
|
+
'}',
|
|
28
|
+
'',
|
|
29
|
+
'output "table_arn" {',
|
|
30
|
+
' description = "ARN of the DynamoDB table, for use in IAM policies granting access to the table. Suffix with /index/* to cover its global secondary indexes."',
|
|
31
|
+
' value = module.dynamodb_table.table_arn',
|
|
32
|
+
'}',
|
|
33
|
+
'',
|
|
34
|
+
'output "kms_key_arn" {',
|
|
35
|
+
' description = "ARN of the KMS key used to encrypt the DynamoDB table, for use in IAM policies granting access to the table. Null when using the AWS owned key (encryption = DEFAULT)."',
|
|
36
|
+
' value = module.dynamodb_table.kms_key_arn',
|
|
37
|
+
'}'
|
|
38
|
+
].join('\n');
|
|
39
|
+
export default async function migration(tree) {
|
|
40
|
+
const nextSteps = [];
|
|
41
|
+
if (!tree.exists(TERRAFORM_DYNAMODB_APP_DIR)) {
|
|
42
|
+
return {
|
|
43
|
+
nextSteps
|
|
44
|
+
}; // This workspace has no Terraform dynamodb modules.
|
|
45
|
+
}
|
|
46
|
+
for (const dirName of tree.children(TERRAFORM_DYNAMODB_APP_DIR)){
|
|
47
|
+
const filePath = joinPathFragments(TERRAFORM_DYNAMODB_APP_DIR, dirName, `${dirName}.tf`);
|
|
48
|
+
if (!tree.exists(filePath)) {
|
|
49
|
+
continue; // Not a dynamodb app module directory.
|
|
50
|
+
}
|
|
51
|
+
if (await matchGritQL(tree, filePath, hcl('`output "table_arn" { $_ }`'))) {
|
|
52
|
+
continue; // Already migrated.
|
|
53
|
+
}
|
|
54
|
+
const RUNTIME_CONFIG_MODULE_BLOCK = hcl('`module "add_to_runtime_config" { $_ }`');
|
|
55
|
+
if (!await matchGritQL(tree, filePath, RUNTIME_CONFIG_MODULE_BLOCK)) {
|
|
56
|
+
nextSteps.push(divergedMessage(filePath));
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
// Appended after the runtime config module call, which the template ends
|
|
60
|
+
// with, matching where the generator now writes the outputs.
|
|
61
|
+
await insertViaGritQL(tree, filePath, hcl(`\`module "add_to_runtime_config" { $body }\` => \`module "add_to_runtime_config" {\n $body\n}\n\n${GRIT_INSERT_PLACEHOLDER}\``), OUTPUTS_TEXT);
|
|
62
|
+
}
|
|
63
|
+
await formatFilesInSubtree(tree);
|
|
64
|
+
return {
|
|
65
|
+
nextSteps
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/dynamodb-terraform-app-module-outputs/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport {\n GRIT_INSERT_PLACEHOLDER,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport {\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../../../utils/shared-constructs-constants.js';\n\n/**\n * Re-export the core dynamodb module's `table_name`, `table_arn` and\n * `kms_key_arn` from each vended per-table Terraform app module\n * (`app/dynamodb/<name>/<name>.tf`).\n *\n * The app module is what a root configuration instantiates, so without these\n * outputs a root module cannot reference the table or its encryption key at\n * all — for example to grant a consumer access to it.\n *\n * These files are generated with `KeepExisting`, so an upgraded workspace keeps\n * a module with no outputs until this runs. Diverged files are left untouched\n * and reported via `nextSteps`.\n */\n\nconst TERRAFORM_DYNAMODB_APP_DIR = `${PACKAGES_DIR}/${SHARED_TERRAFORM_DIR}/src/app/dynamodb`;\n\nconst divergedMessage = (filePath: string) =>\n `${filePath}: has diverged from the generated shape - left untouched. To reference the table from your root Terraform configuration, add table_name, table_arn and kms_key_arn outputs here forwarding the equivalent module.dynamodb_table attributes (see the ts#dynamodb generator's dynamodb app template).`;\n\nconst hcl = (pattern: string) => `language hcl\\n${pattern}`;\n\nconst OUTPUTS_TEXT = [\n 'output \"table_name\" {',\n ' description = \"Name of the DynamoDB table\"',\n ' value = module.dynamodb_table.table_name',\n '}',\n '',\n 'output \"table_arn\" {',\n ' description = \"ARN of the DynamoDB table, for use in IAM policies granting access to the table. Suffix with /index/* to cover its global secondary indexes.\"',\n ' value = module.dynamodb_table.table_arn',\n '}',\n '',\n 'output \"kms_key_arn\" {',\n ' description = \"ARN of the KMS key used to encrypt the DynamoDB table, for use in IAM policies granting access to the table. Null when using the AWS owned key (encryption = DEFAULT).\"',\n ' value = module.dynamodb_table.kms_key_arn',\n '}',\n].join('\\n');\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n if (!tree.exists(TERRAFORM_DYNAMODB_APP_DIR)) {\n return { nextSteps }; // This workspace has no Terraform dynamodb modules.\n }\n\n for (const dirName of tree.children(TERRAFORM_DYNAMODB_APP_DIR)) {\n const filePath = joinPathFragments(\n TERRAFORM_DYNAMODB_APP_DIR,\n dirName,\n `${dirName}.tf`,\n );\n if (!tree.exists(filePath)) {\n continue; // Not a dynamodb app module directory.\n }\n\n if (await matchGritQL(tree, filePath, hcl('`output \"table_arn\" { $_ }`'))) {\n continue; // Already migrated.\n }\n\n const RUNTIME_CONFIG_MODULE_BLOCK = hcl(\n '`module \"add_to_runtime_config\" { $_ }`',\n );\n if (!(await matchGritQL(tree, filePath, RUNTIME_CONFIG_MODULE_BLOCK))) {\n nextSteps.push(divergedMessage(filePath));\n continue;\n }\n\n // Appended after the runtime config module call, which the template ends\n // with, matching where the generator now writes the outputs.\n await insertViaGritQL(\n tree,\n filePath,\n hcl(\n `\\`module \"add_to_runtime_config\" { $body }\\` => \\`module \"add_to_runtime_config\" {\\n $body\\n}\\n\\n${GRIT_INSERT_PLACEHOLDER}\\``,\n ),\n OUTPUTS_TEXT,\n );\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["joinPathFragments","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_TERRAFORM_DIR","TERRAFORM_DYNAMODB_APP_DIR","divergedMessage","filePath","hcl","pattern","OUTPUTS_TEXT","join","migration","tree","nextSteps","exists","dirName","children","RUNTIME_CONFIG_MODULE_BLOCK","push"],"mappings":"AAAA;;;CAGC,GACD,SACEA,iBAAiB,QAGZ,aAAa;AACpB,SACEC,uBAAuB,EACvBC,eAAe,EACfC,WAAW,QACN,wBAAwB;AAC/B,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SACEC,YAAY,EACZC,oBAAoB,QACf,gDAAgD;AAEvD;;;;;;;;;;;;CAYC,GAED,MAAMC,6BAA6B,GAAGF,aAAa,CAAC,EAAEC,qBAAqB,iBAAiB,CAAC;AAE7F,MAAME,kBAAkB,CAACC,WACvB,GAAGA,SAAS,mSAAmS,CAAC;AAElT,MAAMC,MAAM,CAACC,UAAoB,CAAC,cAAc,EAAEA,SAAS;AAE3D,MAAMC,eAAe;IACnB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,CAACC,IAAI,CAAC;AAEP,eAAe,eAAeC,UAC5BC,IAAU;IAEV,MAAMC,YAAsB,EAAE;IAE9B,IAAI,CAACD,KAAKE,MAAM,CAACV,6BAA6B;QAC5C,OAAO;YAAES;QAAU,GAAG,oDAAoD;IAC5E;IAEA,KAAK,MAAME,WAAWH,KAAKI,QAAQ,CAACZ,4BAA6B;QAC/D,MAAME,WAAWT,kBACfO,4BACAW,SACA,GAAGA,QAAQ,GAAG,CAAC;QAEjB,IAAI,CAACH,KAAKE,MAAM,CAACR,WAAW;YAC1B,UAAU,uCAAuC;QACnD;QAEA,IAAI,MAAMN,YAAYY,MAAMN,UAAUC,IAAI,iCAAiC;YACzE,UAAU,oBAAoB;QAChC;QAEA,MAAMU,8BAA8BV,IAClC;QAEF,IAAI,CAAE,MAAMP,YAAYY,MAAMN,UAAUW,8BAA+B;YACrEJ,UAAUK,IAAI,CAACb,gBAAgBC;YAC/B;QACF;QAEA,yEAAyE;QACzE,6DAA6D;QAC7D,MAAMP,gBACJa,MACAN,UACAC,IACE,CAAC,kGAAkG,EAAET,wBAAwB,EAAE,CAAC,GAElIW;IAEJ;IAEA,MAAMR,qBAAqBW;IAE3B,OAAO;QAAEC;IAAU;AACrB"}
|