@aws/nx-plugin 1.0.0-rc.83 → 1.0.0-rc.85
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/generators.json +7 -0
- package/migrations.json +31 -1
- package/package.json +1 -1
- package/src/agentcore-gateway/__snapshots__/generator.spec.ts.snap +51 -2
- package/src/agentcore-harness/__snapshots__/generator.spec.ts.snap +4 -5
- package/src/agentcore-harness/files/project/README.md.template +4 -5
- package/src/internal/test-matrix/generator.js +16 -0
- package/src/internal/test-matrix/generator.js.map +1 -1
- 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/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-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-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/terraform-project-checkov-target-and-bootstrap-destroy/metadata.json +3 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.js +146 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/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/open-api/json-metadata/generator.d.ts +24 -0
- package/src/open-api/json-metadata/generator.js +37 -0
- package/src/open-api/json-metadata/generator.js.map +1 -0
- package/src/open-api/json-metadata/schema.d.js +6 -0
- package/src/open-api/json-metadata/schema.d.js.map +1 -0
- package/src/open-api/json-metadata/schema.d.ts +9 -0
- package/src/open-api/json-metadata/schema.json +20 -0
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +12 -0
- package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +1875 -623
- package/src/py/fast-api/generator.js +2 -1
- package/src/py/fast-api/generator.js.map +1 -1
- 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/sdk/open-api.d.ts +2 -0
- package/src/sdk/open-api.js +2 -1
- package/src/sdk/open-api.js.map +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +1756 -457
- package/src/smithy/ts/api/generator.js +2 -1
- package/src/smithy/ts/api/generator.js.map +1 -1
- package/src/terraform/project/files/application/bootstrap/providers.tf.template +11 -0
- package/src/terraform/project/files/application/scripts/bootstrap-destroy.ts.template +111 -0
- package/src/terraform/project/files/application/src/providers.tf.template +6 -0
- package/src/terraform/project/files/checkov/checkov.yml.template +8 -0
- package/src/terraform/project/files/library/src/main.tf.template +9 -0
- package/src/terraform/project/generator.js +47 -4
- package/src/terraform/project/generator.js.map +1 -1
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +1848 -614
- package/src/trpc/backend/files-operations/scripts/generate-operations.ts.template +40 -0
- package/src/trpc/backend/generator.js +10 -0
- package/src/trpc/backend/generator.js.map +1 -1
- 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/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 +62 -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/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/api-constructs.js +11 -0
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +251 -3
- package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +437 -2
- package/src/utils/api-constructs/files/terraform/core/api/rest/rest-api/rest-api.tf.template +60 -7
- package/src/utils/api-constructs/open-api-metadata.d.ts +20 -3
- package/src/utils/api-constructs/open-api-metadata.js +64 -8
- package/src/utils/api-constructs/open-api-metadata.js.map +1 -1
- package/src/utils/api-constructs/trpc-operations-metadata.d.ts +21 -0
- package/src/utils/api-constructs/trpc-operations-metadata.js +55 -0
- package/src/utils/api-constructs/trpc-operations-metadata.js.map +1 -0
- package/src/utils/dcr-proxy-constructs/files/terraform/app/dcr-proxies/__nameKebabCase__/__nameKebabCase__.tf.template +4 -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 +2 -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/website-constructs/files/terraform/core/static-website/static-website.tf.template +4 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'fs';
|
|
2
|
+
import { dirname } from 'path';
|
|
3
|
+
import { appRouter } from '../src/router<% if (esm) { %>.js<% } %>';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Flattens the router into operation names (dot notation for nested routers)
|
|
7
|
+
* with the path and method each procedure is served on.
|
|
8
|
+
*/
|
|
9
|
+
const toOperations = (
|
|
10
|
+
router: any,
|
|
11
|
+
prefix = '',
|
|
12
|
+
): Record<string, { path: string; method: string }> =>
|
|
13
|
+
Object.fromEntries(
|
|
14
|
+
Object.entries(router._def.procedures).flatMap(
|
|
15
|
+
([name, procedureOrRouter]: [string, any]) => {
|
|
16
|
+
const fullPath = prefix ? `${prefix}.${name}` : name;
|
|
17
|
+
return procedureOrRouter._def?.router
|
|
18
|
+
? Object.entries(toOperations(procedureOrRouter, fullPath))
|
|
19
|
+
: [
|
|
20
|
+
[
|
|
21
|
+
fullPath,
|
|
22
|
+
{
|
|
23
|
+
path: fullPath,
|
|
24
|
+
method:
|
|
25
|
+
procedureOrRouter._def.type === 'mutation' ? 'POST' : 'GET',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
];
|
|
29
|
+
},
|
|
30
|
+
),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// Sorted by operation name so the file is stable and does not churn the Terraform plan
|
|
34
|
+
const operations = Object.fromEntries(
|
|
35
|
+
Object.entries(toOperations(appRouter)).sort(([a], [b]) => a.localeCompare(b)),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const outputFile = process.argv[2];
|
|
39
|
+
mkdirSync(dirname(outputFile), { recursive: true });
|
|
40
|
+
writeFileSync(outputFile, `${JSON.stringify(operations, null, 2)}\n`);
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import tsProjectGenerator from "../../ts/lib/generator.js";
|
|
6
6
|
import { addTsDependencies } from "../../utils/add-dependencies.js";
|
|
7
7
|
import { API_CONSTRUCTS_DEPENDENCIES, API_CONSTRUCTS_PY_DEPENDENCIES, addApiGatewayInfra } from "../../utils/api-constructs/api-constructs.js";
|
|
8
|
+
import { addTrpcOperationsMetadataTarget } from "../../utils/api-constructs/trpc-operations-metadata.js";
|
|
8
9
|
import { addTypeScriptBundleTarget, BUNDLE_DEPENDENCIES } from "../../utils/bundle/bundle.js";
|
|
9
10
|
import { declareDependencies, ownedElsewhere } from "../../utils/declared-dependencies.js";
|
|
10
11
|
import { formatFilesInSubtree } from "../../utils/format.js";
|
|
@@ -216,6 +217,15 @@ export async function tsTrpcApiGenerator(tree, options) {
|
|
|
216
217
|
}, DEPENDENCIES);
|
|
217
218
|
}
|
|
218
219
|
addDependencyToTargetIfNotPresent(projectConfig, 'build', 'bundle');
|
|
220
|
+
// Terraform defines one Lambda function per operation from a generated
|
|
221
|
+
// metadata file; CDK derives the same information from the router's types.
|
|
222
|
+
if (iac === 'terraform' && getIntegrationPattern(options) === 'isolated') {
|
|
223
|
+
addTrpcOperationsMetadataTarget(tree, {
|
|
224
|
+
apiNameKebabCase,
|
|
225
|
+
project: projectConfig,
|
|
226
|
+
templateOptions: esmVars(tree)
|
|
227
|
+
});
|
|
228
|
+
}
|
|
219
229
|
}
|
|
220
230
|
projectConfig.targets = sortObjectKeys(projectConfig.targets);
|
|
221
231
|
updateProjectConfiguration(tree, projectConfig.name, projectConfig);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/trpc/backend/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport tsProjectGenerator from '../../ts/lib/generator.js';\nimport { addTsDependencies } from '../../utils/add-dependencies.js';\nimport {\n API_CONSTRUCTS_DEPENDENCIES,\n API_CONSTRUCTS_PY_DEPENDENCIES,\n addApiGatewayInfra,\n} from '../../utils/api-constructs/api-constructs.js';\nimport {\n addTypeScriptBundleTarget,\n BUNDLE_DEPENDENCIES,\n} from '../../utils/bundle/bundle.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 { esmVars } from '../../utils/module-format.js';\nimport { kebabCase, toClassName } from '../../utils/names.js';\nimport { getNpmScopePrefix } from '../../utils/npm-scope.js';\nimport {\n addDependencyToTargetIfNotPresent,\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../utils/nx.js';\nimport { sortObjectKeys } from '../../utils/object.js';\nimport { getPackageManagerDisplayCommands } from '../../utils/pkg-manager.js';\nimport { assignPort } from '../../utils/port.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 { TsTrpcApiGeneratorSchema } from './schema';\n\n/** The metadata this generator records, which its predicates read. */\nexport interface TsTrpcApiMetadata extends IacMetadata {\n readonly apiName: string;\n readonly apiType: string;\n readonly auth: TsTrpcApiGeneratorSchema['auth'];\n readonly infra: TsTrpcApiGeneratorSchema['infra'];\n readonly integrationPattern: 'isolated' | 'shared';\n}\n\n// Each entry names the branch it belongs to, so the same declaration drives both\n// adding and the version sync.\nexport const DEPENDENCIES = declareDependencies<TsTrpcApiMetadata>()({\n ts: [\n { name: 'aws-xray-sdk-core' },\n { name: 'zod' },\n { name: '@aws-lambda-powertools/logger' },\n { name: '@aws-lambda-powertools/metrics' },\n { name: '@aws-lambda-powertools/parameters' },\n { name: '@aws-lambda-powertools/tracer' },\n { name: '@aws-sdk/client-appconfigdata' },\n { name: '@trpc/server' },\n { name: '@trpc/client' },\n { name: 'aws4fetch' },\n { name: '@aws-sdk/credential-providers' },\n // The custom authorizer handler wraps itself with middy and parses its event.\n { name: '@middy/core', when: (m) => m.auth === 'custom' },\n { name: '@aws-lambda-powertools/parser', when: (m) => m.auth === 'custom' },\n { name: '@types/aws-lambda', dev: true },\n { name: 'cors', dev: true },\n { name: '@types/cors', dev: true },\n // tsx runs the local server from the workspace root.\n { name: 'tsx', dev: true, root: true },\n ...ownedElsewhere(API_CONSTRUCTS_DEPENDENCIES),\n ...ownedElsewhere(BUNDLE_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: ownedElsewhere(API_CONSTRUCTS_PY_DEPENDENCIES),\n});\n\nexport const TRPC_BACKEND_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nconst VALID_TRPC_INTEGRATION_PERMUTATIONS = new Set([\n 'rest-lambda::isolated',\n 'rest-lambda::shared',\n 'http-lambda::isolated',\n 'http-lambda::shared',\n 'none::isolated',\n 'none::shared',\n]);\n\nexport async function tsTrpcApiGenerator(\n tree: Tree,\n options: TsTrpcApiGeneratorSchema,\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 options.infra !== 'none' ? await resolveIac(tree, options.iac) : undefined;\n\n if (options.infra !== 'none') {\n validateTrpcInfraAndIntegrationPatternCombination(options);\n }\n\n const apiNamespace = getNpmScopePrefix(tree);\n const apiNameKebabCase = kebabCase(options.name);\n const apiNameClassName = toClassName(options.name);\n\n const backendName = apiNameKebabCase;\n const backendProjectName = `${apiNamespace}${backendName}`;\n\n let projectExists: boolean;\n try {\n readProjectConfigurationUnqualified(tree, backendProjectName);\n projectExists = true;\n } catch {\n projectExists = false;\n }\n\n if (!projectExists) {\n await tsProjectGenerator(tree, {\n name: backendName,\n directory: options.directory,\n subDirectory: options.subDirectory,\n preferInstallDependencies: false,\n });\n }\n\n const projectConfig = readProjectConfigurationUnqualified(\n tree,\n backendProjectName,\n );\n const backendRoot = projectConfig.root;\n\n const port = assignPort(tree, projectConfig, 2022);\n\n const enhancedOptions = {\n backendProjectName,\n backendProjectAlias: backendProjectName,\n apiNameKebabCase,\n apiNameClassName,\n backendRoot,\n pkgMgrCmd: getPackageManagerDisplayCommands().exec,\n apiGatewayEventType: getApiGatewayEventType(options),\n port,\n ...options,\n ...esmVars(tree),\n };\n\n if (options.infra !== 'none') {\n await sharedConstructsGenerator(\n tree,\n {\n iac,\n },\n DEPENDENCIES,\n );\n\n await addApiGatewayInfra(\n tree,\n {\n apiProjectName: backendProjectName,\n apiNameClassName,\n apiNameKebabCase,\n constructType: options.infra === 'http-lambda' ? 'http' : 'rest',\n backend: {\n type: 'trpc',\n projectAlias: enhancedOptions.backendProjectAlias,\n bundleOutputDir: joinPathFragments('dist', backendRoot, 'bundle'),\n integrationPattern: getIntegrationPattern(options),\n ...(options.auth === 'custom' && {\n authorizerBundleOutputDir: joinPathFragments(\n 'dist',\n backendRoot,\n 'bundle',\n 'authorizer',\n ),\n }),\n },\n auth: options.auth,\n iac,\n },\n DEPENDENCIES,\n );\n }\n\n // Recorded on the project below and read by the declaration's predicates, so\n // the packages added here are exactly the ones the version sync will own.\n const metadata: TsTrpcApiMetadata = {\n apiName: options.name,\n apiType: 'trpc',\n auth: options.auth,\n infra: options.infra,\n integrationPattern: getIntegrationPattern(options),\n ...(iac ? { iac } : {}),\n };\n\n projectConfig.metadata = {\n ...projectConfig.metadata,\n ...metadata,\n } as unknown;\n\n projectConfig.targets.serve = {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: ['tsx --watch src/local-server.ts'],\n cwd: '{projectRoot}',\n },\n };\n\n projectConfig.targets['dev'] = {\n ...projectConfig.targets['dev'],\n ...projectConfig.targets.serve,\n options: {\n ...projectConfig.targets.serve.options,\n env: {\n LOCAL_DEV: 'true',\n },\n },\n };\n\n if (options.infra !== 'none') {\n await addTypeScriptBundleTarget(\n tree,\n projectConfig,\n {\n targetFilePath: 'src/handler.ts',\n external: [/@aws-sdk\\/.*/], // lambda runtime provides aws sdk\n },\n DEPENDENCIES,\n );\n\n if (options.auth === 'custom') {\n await addTypeScriptBundleTarget(\n tree,\n projectConfig,\n {\n targetFilePath: 'src/authorizer.ts',\n bundleOutputDir: 'authorizer',\n external: [/@aws-sdk\\/.*/],\n },\n DEPENDENCIES,\n );\n }\n\n addDependencyToTargetIfNotPresent(projectConfig, 'build', 'bundle');\n }\n\n projectConfig.targets = sortObjectKeys(projectConfig.targets);\n\n updateProjectConfiguration(tree, projectConfig.name, projectConfig);\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n backendRoot,\n enhancedOptions,\n {\n overwriteStrategy: OverwriteStrategy.Overwrite,\n },\n );\n\n tree.delete(joinPathFragments(backendRoot, 'src', 'lib'));\n\n if (options.infra !== 'none' && options.auth === 'custom') {\n const authorizerType = options.infra === 'http-lambda' ? 'http' : 'rest';\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n '..',\n '..',\n 'utils',\n 'api-constructs',\n 'files',\n 'cdk',\n 'authorizer',\n authorizerType,\n ),\n joinPathFragments(backendRoot, 'src'),\n {},\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n }\n\n // Remove streaming schema helper for HTTP APIs (API Gateway HTTP API doesn't support streaming)\n if (options.infra !== 'rest-lambda' && options.infra !== 'none') {\n tree.delete(\n joinPathFragments(backendRoot, 'src', 'schema', 'z-async-iterable.ts'),\n );\n }\n\n addTsDependencies(tree, DEPENDENCIES, {\n metadata,\n projectRoot: backendRoot,\n });\n addGeneratorMetadata(\n tree,\n backendName,\n TRPC_BACKEND_GENERATOR_INFO,\n metadata,\n );\n\n await addGeneratorMetricsIfApplicable(tree, [TRPC_BACKEND_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n}\n\nconst validateTrpcInfraAndIntegrationPatternCombination = (\n options: TsTrpcApiGeneratorSchema,\n) => {\n const integrationPattern = getIntegrationPattern(options);\n const permutation = `${options.infra}::${integrationPattern}`;\n\n if (!VALID_TRPC_INTEGRATION_PERMUTATIONS.has(permutation)) {\n throw new Error(\n `Invalid tRPC infra/integrationPattern combination: ${options.infra} + ${integrationPattern}.`,\n );\n }\n};\n\nconst getIntegrationPattern = (\n options: TsTrpcApiGeneratorSchema,\n): 'isolated' | 'shared' => {\n return options.integrationPattern ?? 'isolated';\n};\n\nconst getApiGatewayEventType = (options: TsTrpcApiGeneratorSchema): string => {\n if (options.infra === 'rest-lambda') {\n return 'APIGatewayProxyEvent';\n }\n if (options.auth === 'iam') {\n return 'APIGatewayProxyEventV2WithIAMAuthorizer';\n } else if (options.auth === 'cognito') {\n return 'APIGatewayProxyEventV2WithJWTAuthorizer';\n }\n return 'APIGatewayProxyEventV2';\n};\n\nexport default tsTrpcApiGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","tsProjectGenerator","addTsDependencies","API_CONSTRUCTS_DEPENDENCIES","API_CONSTRUCTS_PY_DEPENDENCIES","addApiGatewayInfra","addTypeScriptBundleTarget","BUNDLE_DEPENDENCIES","declareDependencies","ownedElsewhere","formatFilesInSubtree","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","esmVars","kebabCase","toClassName","getNpmScopePrefix","addDependencyToTargetIfNotPresent","addGeneratorMetadata","getGeneratorInfo","readProjectConfigurationUnqualified","sortObjectKeys","getPackageManagerDisplayCommands","assignPort","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","DEPENDENCIES","ts","name","when","m","auth","dev","root","py","TRPC_BACKEND_GENERATOR_INFO","filename","VALID_TRPC_INTEGRATION_PERMUTATIONS","Set","tsTrpcApiGenerator","tree","options","iac","infra","undefined","validateTrpcInfraAndIntegrationPatternCombination","apiNamespace","apiNameKebabCase","apiNameClassName","backendName","backendProjectName","projectExists","directory","subDirectory","preferInstallDependencies","projectConfig","backendRoot","port","enhancedOptions","backendProjectAlias","pkgMgrCmd","exec","apiGatewayEventType","getApiGatewayEventType","apiProjectName","constructType","backend","type","projectAlias","bundleOutputDir","integrationPattern","getIntegrationPattern","authorizerBundleOutputDir","metadata","apiName","apiType","targets","serve","executor","continuous","commands","cwd","env","LOCAL_DEV","targetFilePath","external","dirname","overwriteStrategy","Overwrite","delete","authorizerType","KeepExisting","projectRoot","languages","permutation","has","Error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/trpc/backend/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport tsProjectGenerator from '../../ts/lib/generator.js';\nimport { addTsDependencies } from '../../utils/add-dependencies.js';\nimport {\n API_CONSTRUCTS_DEPENDENCIES,\n API_CONSTRUCTS_PY_DEPENDENCIES,\n addApiGatewayInfra,\n} from '../../utils/api-constructs/api-constructs.js';\nimport { addTrpcOperationsMetadataTarget } from '../../utils/api-constructs/trpc-operations-metadata.js';\nimport {\n addTypeScriptBundleTarget,\n BUNDLE_DEPENDENCIES,\n} from '../../utils/bundle/bundle.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 { esmVars } from '../../utils/module-format.js';\nimport { kebabCase, toClassName } from '../../utils/names.js';\nimport { getNpmScopePrefix } from '../../utils/npm-scope.js';\nimport {\n addDependencyToTargetIfNotPresent,\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../utils/nx.js';\nimport { sortObjectKeys } from '../../utils/object.js';\nimport { getPackageManagerDisplayCommands } from '../../utils/pkg-manager.js';\nimport { assignPort } from '../../utils/port.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 { TsTrpcApiGeneratorSchema } from './schema';\n\n/** The metadata this generator records, which its predicates read. */\nexport interface TsTrpcApiMetadata extends IacMetadata {\n readonly apiName: string;\n readonly apiType: string;\n readonly auth: TsTrpcApiGeneratorSchema['auth'];\n readonly infra: TsTrpcApiGeneratorSchema['infra'];\n readonly integrationPattern: 'isolated' | 'shared';\n}\n\n// Each entry names the branch it belongs to, so the same declaration drives both\n// adding and the version sync.\nexport const DEPENDENCIES = declareDependencies<TsTrpcApiMetadata>()({\n ts: [\n { name: 'aws-xray-sdk-core' },\n { name: 'zod' },\n { name: '@aws-lambda-powertools/logger' },\n { name: '@aws-lambda-powertools/metrics' },\n { name: '@aws-lambda-powertools/parameters' },\n { name: '@aws-lambda-powertools/tracer' },\n { name: '@aws-sdk/client-appconfigdata' },\n { name: '@trpc/server' },\n { name: '@trpc/client' },\n { name: 'aws4fetch' },\n { name: '@aws-sdk/credential-providers' },\n // The custom authorizer handler wraps itself with middy and parses its event.\n { name: '@middy/core', when: (m) => m.auth === 'custom' },\n { name: '@aws-lambda-powertools/parser', when: (m) => m.auth === 'custom' },\n { name: '@types/aws-lambda', dev: true },\n { name: 'cors', dev: true },\n { name: '@types/cors', dev: true },\n // tsx runs the local server from the workspace root.\n { name: 'tsx', dev: true, root: true },\n ...ownedElsewhere(API_CONSTRUCTS_DEPENDENCIES),\n ...ownedElsewhere(BUNDLE_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: ownedElsewhere(API_CONSTRUCTS_PY_DEPENDENCIES),\n});\n\nexport const TRPC_BACKEND_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nconst VALID_TRPC_INTEGRATION_PERMUTATIONS = new Set([\n 'rest-lambda::isolated',\n 'rest-lambda::shared',\n 'http-lambda::isolated',\n 'http-lambda::shared',\n 'none::isolated',\n 'none::shared',\n]);\n\nexport async function tsTrpcApiGenerator(\n tree: Tree,\n options: TsTrpcApiGeneratorSchema,\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 options.infra !== 'none' ? await resolveIac(tree, options.iac) : undefined;\n\n if (options.infra !== 'none') {\n validateTrpcInfraAndIntegrationPatternCombination(options);\n }\n\n const apiNamespace = getNpmScopePrefix(tree);\n const apiNameKebabCase = kebabCase(options.name);\n const apiNameClassName = toClassName(options.name);\n\n const backendName = apiNameKebabCase;\n const backendProjectName = `${apiNamespace}${backendName}`;\n\n let projectExists: boolean;\n try {\n readProjectConfigurationUnqualified(tree, backendProjectName);\n projectExists = true;\n } catch {\n projectExists = false;\n }\n\n if (!projectExists) {\n await tsProjectGenerator(tree, {\n name: backendName,\n directory: options.directory,\n subDirectory: options.subDirectory,\n preferInstallDependencies: false,\n });\n }\n\n const projectConfig = readProjectConfigurationUnqualified(\n tree,\n backendProjectName,\n );\n const backendRoot = projectConfig.root;\n\n const port = assignPort(tree, projectConfig, 2022);\n\n const enhancedOptions = {\n backendProjectName,\n backendProjectAlias: backendProjectName,\n apiNameKebabCase,\n apiNameClassName,\n backendRoot,\n pkgMgrCmd: getPackageManagerDisplayCommands().exec,\n apiGatewayEventType: getApiGatewayEventType(options),\n port,\n ...options,\n ...esmVars(tree),\n };\n\n if (options.infra !== 'none') {\n await sharedConstructsGenerator(\n tree,\n {\n iac,\n },\n DEPENDENCIES,\n );\n\n await addApiGatewayInfra(\n tree,\n {\n apiProjectName: backendProjectName,\n apiNameClassName,\n apiNameKebabCase,\n constructType: options.infra === 'http-lambda' ? 'http' : 'rest',\n backend: {\n type: 'trpc',\n projectAlias: enhancedOptions.backendProjectAlias,\n bundleOutputDir: joinPathFragments('dist', backendRoot, 'bundle'),\n integrationPattern: getIntegrationPattern(options),\n ...(options.auth === 'custom' && {\n authorizerBundleOutputDir: joinPathFragments(\n 'dist',\n backendRoot,\n 'bundle',\n 'authorizer',\n ),\n }),\n },\n auth: options.auth,\n iac,\n },\n DEPENDENCIES,\n );\n }\n\n // Recorded on the project below and read by the declaration's predicates, so\n // the packages added here are exactly the ones the version sync will own.\n const metadata: TsTrpcApiMetadata = {\n apiName: options.name,\n apiType: 'trpc',\n auth: options.auth,\n infra: options.infra,\n integrationPattern: getIntegrationPattern(options),\n ...(iac ? { iac } : {}),\n };\n\n projectConfig.metadata = {\n ...projectConfig.metadata,\n ...metadata,\n } as unknown;\n\n projectConfig.targets.serve = {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: ['tsx --watch src/local-server.ts'],\n cwd: '{projectRoot}',\n },\n };\n\n projectConfig.targets['dev'] = {\n ...projectConfig.targets['dev'],\n ...projectConfig.targets.serve,\n options: {\n ...projectConfig.targets.serve.options,\n env: {\n LOCAL_DEV: 'true',\n },\n },\n };\n\n if (options.infra !== 'none') {\n await addTypeScriptBundleTarget(\n tree,\n projectConfig,\n {\n targetFilePath: 'src/handler.ts',\n external: [/@aws-sdk\\/.*/], // lambda runtime provides aws sdk\n },\n DEPENDENCIES,\n );\n\n if (options.auth === 'custom') {\n await addTypeScriptBundleTarget(\n tree,\n projectConfig,\n {\n targetFilePath: 'src/authorizer.ts',\n bundleOutputDir: 'authorizer',\n external: [/@aws-sdk\\/.*/],\n },\n DEPENDENCIES,\n );\n }\n\n addDependencyToTargetIfNotPresent(projectConfig, 'build', 'bundle');\n\n // Terraform defines one Lambda function per operation from a generated\n // metadata file; CDK derives the same information from the router's types.\n if (iac === 'terraform' && getIntegrationPattern(options) === 'isolated') {\n addTrpcOperationsMetadataTarget(tree, {\n apiNameKebabCase,\n project: projectConfig,\n templateOptions: esmVars(tree),\n });\n }\n }\n\n projectConfig.targets = sortObjectKeys(projectConfig.targets);\n\n updateProjectConfiguration(tree, projectConfig.name, projectConfig);\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n backendRoot,\n enhancedOptions,\n {\n overwriteStrategy: OverwriteStrategy.Overwrite,\n },\n );\n\n tree.delete(joinPathFragments(backendRoot, 'src', 'lib'));\n\n if (options.infra !== 'none' && options.auth === 'custom') {\n const authorizerType = options.infra === 'http-lambda' ? 'http' : 'rest';\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n '..',\n '..',\n 'utils',\n 'api-constructs',\n 'files',\n 'cdk',\n 'authorizer',\n authorizerType,\n ),\n joinPathFragments(backendRoot, 'src'),\n {},\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n }\n\n // Remove streaming schema helper for HTTP APIs (API Gateway HTTP API doesn't support streaming)\n if (options.infra !== 'rest-lambda' && options.infra !== 'none') {\n tree.delete(\n joinPathFragments(backendRoot, 'src', 'schema', 'z-async-iterable.ts'),\n );\n }\n\n addTsDependencies(tree, DEPENDENCIES, {\n metadata,\n projectRoot: backendRoot,\n });\n addGeneratorMetadata(\n tree,\n backendName,\n TRPC_BACKEND_GENERATOR_INFO,\n metadata,\n );\n\n await addGeneratorMetricsIfApplicable(tree, [TRPC_BACKEND_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n}\n\nconst validateTrpcInfraAndIntegrationPatternCombination = (\n options: TsTrpcApiGeneratorSchema,\n) => {\n const integrationPattern = getIntegrationPattern(options);\n const permutation = `${options.infra}::${integrationPattern}`;\n\n if (!VALID_TRPC_INTEGRATION_PERMUTATIONS.has(permutation)) {\n throw new Error(\n `Invalid tRPC infra/integrationPattern combination: ${options.infra} + ${integrationPattern}.`,\n );\n }\n};\n\nconst getIntegrationPattern = (\n options: TsTrpcApiGeneratorSchema,\n): 'isolated' | 'shared' => {\n return options.integrationPattern ?? 'isolated';\n};\n\nconst getApiGatewayEventType = (options: TsTrpcApiGeneratorSchema): string => {\n if (options.infra === 'rest-lambda') {\n return 'APIGatewayProxyEvent';\n }\n if (options.auth === 'iam') {\n return 'APIGatewayProxyEventV2WithIAMAuthorizer';\n } else if (options.auth === 'cognito') {\n return 'APIGatewayProxyEventV2WithJWTAuthorizer';\n }\n return 'APIGatewayProxyEventV2';\n};\n\nexport default tsTrpcApiGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","tsProjectGenerator","addTsDependencies","API_CONSTRUCTS_DEPENDENCIES","API_CONSTRUCTS_PY_DEPENDENCIES","addApiGatewayInfra","addTrpcOperationsMetadataTarget","addTypeScriptBundleTarget","BUNDLE_DEPENDENCIES","declareDependencies","ownedElsewhere","formatFilesInSubtree","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","esmVars","kebabCase","toClassName","getNpmScopePrefix","addDependencyToTargetIfNotPresent","addGeneratorMetadata","getGeneratorInfo","readProjectConfigurationUnqualified","sortObjectKeys","getPackageManagerDisplayCommands","assignPort","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","DEPENDENCIES","ts","name","when","m","auth","dev","root","py","TRPC_BACKEND_GENERATOR_INFO","filename","VALID_TRPC_INTEGRATION_PERMUTATIONS","Set","tsTrpcApiGenerator","tree","options","iac","infra","undefined","validateTrpcInfraAndIntegrationPatternCombination","apiNamespace","apiNameKebabCase","apiNameClassName","backendName","backendProjectName","projectExists","directory","subDirectory","preferInstallDependencies","projectConfig","backendRoot","port","enhancedOptions","backendProjectAlias","pkgMgrCmd","exec","apiGatewayEventType","getApiGatewayEventType","apiProjectName","constructType","backend","type","projectAlias","bundleOutputDir","integrationPattern","getIntegrationPattern","authorizerBundleOutputDir","metadata","apiName","apiType","targets","serve","executor","continuous","commands","cwd","env","LOCAL_DEV","targetFilePath","external","project","templateOptions","dirname","overwriteStrategy","Overwrite","delete","authorizerType","KeepExisting","projectRoot","languages","permutation","has","Error"],"mappings":"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"}
|
|
@@ -982,6 +982,10 @@ export * from './workspace.js';
|
|
|
982
982
|
exports[`ts#agent generator > should match snapshot for Terraform generated files > terraform-agent.tf 1`] = `
|
|
983
983
|
"terraform {
|
|
984
984
|
required_providers {
|
|
985
|
+
aws = {
|
|
986
|
+
source = "hashicorp/aws"
|
|
987
|
+
version = "6.61.0"
|
|
988
|
+
}
|
|
985
989
|
random = {
|
|
986
990
|
source = "hashicorp/random"
|
|
987
991
|
version = "3.9.0"
|
|
@@ -1293,6 +1297,10 @@ exports[`ts#agent generator > should match snapshot for Terraform generated file
|
|
|
1293
1297
|
source = "hashicorp/aws"
|
|
1294
1298
|
version = "6.61.0"
|
|
1295
1299
|
}
|
|
1300
|
+
external = {
|
|
1301
|
+
source = "hashicorp/external"
|
|
1302
|
+
version = "2.4.1"
|
|
1303
|
+
}
|
|
1296
1304
|
null = {
|
|
1297
1305
|
source = "hashicorp/null"
|
|
1298
1306
|
version = "3.3.1"
|
|
@@ -147,6 +147,10 @@ exports[`ts-lambda-function generator > terraform iac > should generate terrafor
|
|
|
147
147
|
source = "hashicorp/archive"
|
|
148
148
|
version = "2.8.0"
|
|
149
149
|
}
|
|
150
|
+
random = {
|
|
151
|
+
source = "hashicorp/random"
|
|
152
|
+
version = "3.9.0"
|
|
153
|
+
}
|
|
150
154
|
}
|
|
151
155
|
}
|
|
152
156
|
|
|
@@ -328,6 +332,10 @@ exports[`ts-lambda-function generator > terraform iac > should match snapshot fo
|
|
|
328
332
|
source = "hashicorp/archive"
|
|
329
333
|
version = "2.8.0"
|
|
330
334
|
}
|
|
335
|
+
random = {
|
|
336
|
+
source = "hashicorp/random"
|
|
337
|
+
version = "3.9.0"
|
|
338
|
+
}
|
|
331
339
|
}
|
|
332
340
|
}
|
|
333
341
|
|
|
@@ -157,6 +157,10 @@ exports[`ts#mcp-server generator > should match snapshot for Terraform generated
|
|
|
157
157
|
source = "hashicorp/aws"
|
|
158
158
|
version = "6.61.0"
|
|
159
159
|
}
|
|
160
|
+
external = {
|
|
161
|
+
source = "hashicorp/external"
|
|
162
|
+
version = "2.4.1"
|
|
163
|
+
}
|
|
160
164
|
null = {
|
|
161
165
|
source = "hashicorp/null"
|
|
162
166
|
version = "3.3.1"
|
|
@@ -539,6 +539,20 @@ export interface AuroraDatabaseProps extends _AuroraDatabaseProps {
|
|
|
539
539
|
* @default true
|
|
540
540
|
*/
|
|
541
541
|
readonly enablePerformanceInsights?: boolean;
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Minimum Aurora Serverless v2 ACUs.
|
|
545
|
+
*
|
|
546
|
+
* @default 0.5
|
|
547
|
+
*/
|
|
548
|
+
readonly serverlessV2MinCapacity?: number;
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Maximum Aurora Serverless v2 ACUs.
|
|
552
|
+
*
|
|
553
|
+
* @default 4
|
|
554
|
+
*/
|
|
555
|
+
readonly serverlessV2MaxCapacity?: number;
|
|
542
556
|
}
|
|
543
557
|
|
|
544
558
|
/**
|
|
@@ -568,6 +582,8 @@ export abstract class AuroraDatabase extends Construct {
|
|
|
568
582
|
enableKeyRotation = true,
|
|
569
583
|
enableCloudwatchLogs = true,
|
|
570
584
|
enablePerformanceInsights = true,
|
|
585
|
+
serverlessV2MinCapacity = 0.5,
|
|
586
|
+
serverlessV2MaxCapacity = 4,
|
|
571
587
|
engine,
|
|
572
588
|
engineVersion,
|
|
573
589
|
...clusterProps
|
|
@@ -583,6 +599,8 @@ export abstract class AuroraDatabase extends Construct {
|
|
|
583
599
|
vpc,
|
|
584
600
|
vpcSubnets,
|
|
585
601
|
engine: engine.clusterEngine(engineVersion ?? engine.defaultVersion),
|
|
602
|
+
serverlessV2MinCapacity,
|
|
603
|
+
serverlessV2MaxCapacity,
|
|
586
604
|
writer:
|
|
587
605
|
writer ??
|
|
588
606
|
ClusterInstance.serverlessV2('writer', {
|
|
@@ -1562,6 +1580,10 @@ exports[`ts#rdb generator > should generate terraform modules when iac is Terraf
|
|
|
1562
1580
|
source = "hashicorp/aws"
|
|
1563
1581
|
version = "6.61.0"
|
|
1564
1582
|
}
|
|
1583
|
+
external = {
|
|
1584
|
+
source = "hashicorp/external"
|
|
1585
|
+
version = "2.4.1"
|
|
1586
|
+
}
|
|
1565
1587
|
null = {
|
|
1566
1588
|
source = "hashicorp/null"
|
|
1567
1589
|
version = "3.3.1"
|
|
@@ -1643,9 +1665,9 @@ variable "enable_credential_rotation" {
|
|
|
1643
1665
|
}
|
|
1644
1666
|
|
|
1645
1667
|
variable "enable_cloudwatch_logs" {
|
|
1646
|
-
description = "Whether to export Aurora engine logs to CloudWatch. PostgreSQL
|
|
1668
|
+
description = "Whether to export Aurora engine logs to CloudWatch. PostgreSQL logs DDL statements only (log_statement=ddl); MySQL enables Advanced Auditing scoped to connections and DDL (server_audit_events=CONNECT,QUERY_DDL). Neither logs statement parameter values, to avoid leaking PII into log data."
|
|
1647
1669
|
type = bool
|
|
1648
|
-
default =
|
|
1670
|
+
default = true
|
|
1649
1671
|
}
|
|
1650
1672
|
|
|
1651
1673
|
variable "enable_performance_insights" {
|
|
@@ -1666,6 +1688,12 @@ variable "enable_backup" {
|
|
|
1666
1688
|
default = false
|
|
1667
1689
|
}
|
|
1668
1690
|
|
|
1691
|
+
variable "enable_key_rotation" {
|
|
1692
|
+
description = "Whether to enable automatic key rotation on the KMS key used to encrypt the Aurora cluster and its credentials secret."
|
|
1693
|
+
type = bool
|
|
1694
|
+
default = true
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1669
1697
|
variable "tags" {
|
|
1670
1698
|
description = "Tags to apply to all resources."
|
|
1671
1699
|
type = map(string)
|
|
@@ -1725,6 +1753,7 @@ module "aurora" {
|
|
|
1725
1753
|
enable_performance_insights = var.enable_performance_insights
|
|
1726
1754
|
performance_insights_retention_period = var.performance_insights_retention_period
|
|
1727
1755
|
enable_backup = var.enable_backup
|
|
1756
|
+
enable_key_rotation = var.enable_key_rotation
|
|
1728
1757
|
tags = var.tags
|
|
1729
1758
|
}
|
|
1730
1759
|
|
|
@@ -3054,6 +3083,10 @@ exports[`ts#rdb generator > should generate terraform modules with MySQL engine
|
|
|
3054
3083
|
source = "hashicorp/aws"
|
|
3055
3084
|
version = "6.61.0"
|
|
3056
3085
|
}
|
|
3086
|
+
external = {
|
|
3087
|
+
source = "hashicorp/external"
|
|
3088
|
+
version = "2.4.1"
|
|
3089
|
+
}
|
|
3057
3090
|
null = {
|
|
3058
3091
|
source = "hashicorp/null"
|
|
3059
3092
|
version = "3.3.1"
|
|
@@ -3135,9 +3168,9 @@ variable "enable_credential_rotation" {
|
|
|
3135
3168
|
}
|
|
3136
3169
|
|
|
3137
3170
|
variable "enable_cloudwatch_logs" {
|
|
3138
|
-
description = "Whether to export Aurora engine logs to CloudWatch. PostgreSQL
|
|
3171
|
+
description = "Whether to export Aurora engine logs to CloudWatch. PostgreSQL logs DDL statements only (log_statement=ddl); MySQL enables Advanced Auditing scoped to connections and DDL (server_audit_events=CONNECT,QUERY_DDL). Neither logs statement parameter values, to avoid leaking PII into log data."
|
|
3139
3172
|
type = bool
|
|
3140
|
-
default =
|
|
3173
|
+
default = true
|
|
3141
3174
|
}
|
|
3142
3175
|
|
|
3143
3176
|
variable "enable_performance_insights" {
|
|
@@ -3158,6 +3191,12 @@ variable "enable_backup" {
|
|
|
3158
3191
|
default = false
|
|
3159
3192
|
}
|
|
3160
3193
|
|
|
3194
|
+
variable "enable_key_rotation" {
|
|
3195
|
+
description = "Whether to enable automatic key rotation on the KMS key used to encrypt the Aurora cluster and its credentials secret."
|
|
3196
|
+
type = bool
|
|
3197
|
+
default = true
|
|
3198
|
+
}
|
|
3199
|
+
|
|
3161
3200
|
variable "tags" {
|
|
3162
3201
|
description = "Tags to apply to all resources."
|
|
3163
3202
|
type = map(string)
|
|
@@ -3217,6 +3256,7 @@ module "aurora" {
|
|
|
3217
3256
|
enable_performance_insights = var.enable_performance_insights
|
|
3218
3257
|
performance_insights_retention_period = var.performance_insights_retention_period
|
|
3219
3258
|
enable_backup = var.enable_backup
|
|
3259
|
+
enable_key_rotation = var.enable_key_rotation
|
|
3220
3260
|
tags = var.tags
|
|
3221
3261
|
}
|
|
3222
3262
|
|
|
@@ -4344,6 +4384,20 @@ export interface AuroraDatabaseProps extends _AuroraDatabaseProps {
|
|
|
4344
4384
|
* @default true
|
|
4345
4385
|
*/
|
|
4346
4386
|
readonly enablePerformanceInsights?: boolean;
|
|
4387
|
+
|
|
4388
|
+
/**
|
|
4389
|
+
* Minimum Aurora Serverless v2 ACUs.
|
|
4390
|
+
*
|
|
4391
|
+
* @default 0.5
|
|
4392
|
+
*/
|
|
4393
|
+
readonly serverlessV2MinCapacity?: number;
|
|
4394
|
+
|
|
4395
|
+
/**
|
|
4396
|
+
* Maximum Aurora Serverless v2 ACUs.
|
|
4397
|
+
*
|
|
4398
|
+
* @default 4
|
|
4399
|
+
*/
|
|
4400
|
+
readonly serverlessV2MaxCapacity?: number;
|
|
4347
4401
|
}
|
|
4348
4402
|
|
|
4349
4403
|
/**
|
|
@@ -4373,6 +4427,8 @@ export abstract class AuroraDatabase extends Construct {
|
|
|
4373
4427
|
enableKeyRotation = true,
|
|
4374
4428
|
enableCloudwatchLogs = true,
|
|
4375
4429
|
enablePerformanceInsights = true,
|
|
4430
|
+
serverlessV2MinCapacity = 0.5,
|
|
4431
|
+
serverlessV2MaxCapacity = 4,
|
|
4376
4432
|
engine,
|
|
4377
4433
|
engineVersion,
|
|
4378
4434
|
...clusterProps
|
|
@@ -4388,6 +4444,8 @@ export abstract class AuroraDatabase extends Construct {
|
|
|
4388
4444
|
vpc,
|
|
4389
4445
|
vpcSubnets,
|
|
4390
4446
|
engine: engine.clusterEngine(engineVersion ?? engine.defaultVersion),
|
|
4447
|
+
serverlessV2MinCapacity,
|
|
4448
|
+
serverlessV2MaxCapacity,
|
|
4391
4449
|
writer:
|
|
4392
4450
|
writer ??
|
|
4393
4451
|
ClusterInstance.serverlessV2('writer', {
|
|
@@ -134,6 +134,10 @@ exports[`react-website generator > TailwindCSS integration > terraform iac > sho
|
|
|
134
134
|
version = "6.61.0"
|
|
135
135
|
configuration_aliases = [aws.us_east_1]
|
|
136
136
|
}
|
|
137
|
+
null = {
|
|
138
|
+
source = "hashicorp/null"
|
|
139
|
+
version = "3.3.1"
|
|
140
|
+
}
|
|
137
141
|
random = {
|
|
138
142
|
source = "hashicorp/random"
|
|
139
143
|
version = "3.9.0"
|
|
@@ -118,6 +118,8 @@ import {
|
|
|
118
118
|
CfnWebACLAssociation,
|
|
119
119
|
} from 'aws-cdk-lib/aws-wafv2';
|
|
120
120
|
import { LogGroup, RetentionDays } from 'aws-cdk-lib/aws-logs';
|
|
121
|
+
import { Key } from 'aws-cdk-lib/aws-kms';
|
|
122
|
+
import { Effect, PolicyStatement, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
|
|
121
123
|
import { Construct } from 'constructs';
|
|
122
124
|
import { RuntimeConfig } from './runtime-config.js';
|
|
123
125
|
import { Distribution } from 'aws-cdk-lib/aws-cloudfront';
|
|
@@ -354,18 +356,43 @@ export class UserIdentity extends Construct {
|
|
|
354
356
|
webAclArn: webAcl.attrArn,
|
|
355
357
|
});
|
|
356
358
|
|
|
357
|
-
//
|
|
358
|
-
//
|
|
359
|
+
// The log group name must start with \`aws-waf-logs-\` to satisfy the WAFv2
|
|
360
|
+
// logging destination requirement.
|
|
361
|
+
const stack = Stack.of(this);
|
|
362
|
+
const wafLogGroupName = \`aws-waf-logs-\${id}-\${this.node.addr.slice(-8)}\`;
|
|
363
|
+
|
|
364
|
+
// KMS key for encrypting WAF logs at rest, usable by CloudWatch Logs
|
|
365
|
+
const logsKey = new Key(this, 'WebAclLogsKey', {
|
|
366
|
+
enableKeyRotation: true,
|
|
367
|
+
});
|
|
368
|
+
logsKey.addToResourcePolicy(
|
|
369
|
+
new PolicyStatement({
|
|
370
|
+
effect: Effect.ALLOW,
|
|
371
|
+
principals: [
|
|
372
|
+
new ServicePrincipal(\`logs.\${stack.region}.amazonaws.com\`),
|
|
373
|
+
],
|
|
374
|
+
actions: [
|
|
375
|
+
'kms:Encrypt',
|
|
376
|
+
'kms:Decrypt',
|
|
377
|
+
'kms:ReEncrypt*',
|
|
378
|
+
'kms:GenerateDataKey*',
|
|
379
|
+
'kms:DescribeKey',
|
|
380
|
+
],
|
|
381
|
+
resources: ['*'],
|
|
382
|
+
conditions: {
|
|
383
|
+
ArnEquals: {
|
|
384
|
+
'kms:EncryptionContext:aws:logs:arn': \`arn:aws:logs:\${stack.region}:\${stack.account}:log-group:\${wafLogGroupName}\`,
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
}),
|
|
388
|
+
);
|
|
389
|
+
|
|
359
390
|
const wafLogGroup = new LogGroup(this, 'WebAclLogs', {
|
|
360
|
-
logGroupName:
|
|
391
|
+
logGroupName: wafLogGroupName,
|
|
361
392
|
retention: RetentionDays.ONE_MONTH,
|
|
393
|
+
encryptionKey: logsKey,
|
|
362
394
|
removalPolicy: RemovalPolicy.DESTROY,
|
|
363
395
|
});
|
|
364
|
-
suppressRules(
|
|
365
|
-
wafLogGroup,
|
|
366
|
-
['CKV_AWS_158'],
|
|
367
|
-
'Using default CloudWatch log encryption for WAF logs',
|
|
368
|
-
);
|
|
369
396
|
|
|
370
397
|
new CfnLoggingConfiguration(this, 'WebAclLoggingConfig', {
|
|
371
398
|
resourceArn: webAcl.attrArn,
|
|
@@ -35,7 +35,10 @@ export interface <%- nameClassName %>Props
|
|
|
35
35
|
executionRole?: iam.IRole;
|
|
36
36
|
/** Model resources the generated execution role may invoke. */
|
|
37
37
|
modelResourceArns?: string[];
|
|
38
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Tools the Harness may use. Defaults to none; pass `['@builtin']` for every
|
|
40
|
+
* built-in tool, or name individual tools.
|
|
41
|
+
*/
|
|
39
42
|
allowedTools?: agentcore.CfnHarnessProps['allowedTools'];
|
|
40
43
|
/**
|
|
41
44
|
* Run the Harness in a VPC so it can reach private resources. Selects private
|
|
@@ -68,6 +71,9 @@ export class <%- nameClassName %>
|
|
|
68
71
|
`arn:${stack.partition}:bedrock:*::foundation-model/*`,
|
|
69
72
|
`arn:${stack.partition}:bedrock:${stack.region}:${stack.account}:*`,
|
|
70
73
|
],
|
|
74
|
+
// The service treats an absent allowedTools as every tool, so this
|
|
75
|
+
// defaults to none and is always passed explicitly.
|
|
76
|
+
allowedTools = [],
|
|
71
77
|
vpc,
|
|
72
78
|
vpcSubnets,
|
|
73
79
|
securityGroups,
|
|
@@ -137,6 +143,29 @@ export class <%- nameClassName %>
|
|
|
137
143
|
actions: ['sts:GetServiceBearerToken'],
|
|
138
144
|
resources: ['*'],
|
|
139
145
|
}),
|
|
146
|
+
// In a VPC the Harness pulls its managed container from a private ECR
|
|
147
|
+
// repository in the region rather than ECR Public. The repository is
|
|
148
|
+
// service-owned, hence the wildcard account.
|
|
149
|
+
...(vpc
|
|
150
|
+
? [
|
|
151
|
+
new iam.PolicyStatement({
|
|
152
|
+
sid: 'EcrManagedImagePull',
|
|
153
|
+
actions: [
|
|
154
|
+
'ecr:BatchGetImage',
|
|
155
|
+
'ecr:GetDownloadUrlForLayer',
|
|
156
|
+
'ecr:BatchCheckLayerAvailability',
|
|
157
|
+
],
|
|
158
|
+
resources: [
|
|
159
|
+
`arn:${stack.partition}:ecr:${stack.region}:*:repository/harness-*`,
|
|
160
|
+
],
|
|
161
|
+
}),
|
|
162
|
+
new iam.PolicyStatement({
|
|
163
|
+
sid: 'EcrManagedImageToken',
|
|
164
|
+
actions: ['ecr:GetAuthorizationToken'],
|
|
165
|
+
resources: ['*'],
|
|
166
|
+
}),
|
|
167
|
+
]
|
|
168
|
+
: []),
|
|
140
169
|
new iam.PolicyStatement({
|
|
141
170
|
sid: 'XRayTracingAccess',
|
|
142
171
|
actions: [
|
|
@@ -239,6 +268,14 @@ export class <%- nameClassName %>
|
|
|
239
268
|
'XRayTracingAccess: X-Ray segment and sampling APIs have no resource-level permission.',
|
|
240
269
|
isPolicy,
|
|
241
270
|
);
|
|
271
|
+
if (vpc) {
|
|
272
|
+
suppressRules(
|
|
273
|
+
this.executionRole,
|
|
274
|
+
WILDCARD_IAM_RULES,
|
|
275
|
+
'EcrManagedImageToken: ecr:GetAuthorizationToken has no resource-level permission.',
|
|
276
|
+
isPolicy,
|
|
277
|
+
);
|
|
278
|
+
}
|
|
242
279
|
}
|
|
243
280
|
|
|
244
281
|
// Rendered lazily so security groups added through `connections` after
|
|
@@ -281,6 +318,7 @@ export class <%- nameClassName %>
|
|
|
281
318
|
},
|
|
282
319
|
systemPrompt: [{ text: systemPrompt }],
|
|
283
320
|
...harnessProps,
|
|
321
|
+
allowedTools,
|
|
284
322
|
// Set after harnessProps so the deployed name always matches the
|
|
285
323
|
// execution role's workload-identity resource pattern.
|
|
286
324
|
harnessName,
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
<%_ const hasSessionBucket = session === 's3' || session === 'dynamodb-s3'; _%>
|
|
2
|
-
<%_
|
|
2
|
+
<%_ const usesAws = hasSessionBucket || auth === 'cognito'; _%>
|
|
3
|
+
<%_ if (usesAws) { _%>
|
|
3
4
|
terraform {
|
|
4
5
|
required_providers {
|
|
6
|
+
aws = {
|
|
7
|
+
source = "hashicorp/aws"
|
|
8
|
+
version = "<%- awsProviderVersion %>"
|
|
9
|
+
}
|
|
10
|
+
<%_ if (hasSessionBucket) { _%>
|
|
5
11
|
random = {
|
|
6
12
|
source = "hashicorp/random"
|
|
7
13
|
version = "<%- randomProviderVersion %>"
|
|
8
14
|
}
|
|
15
|
+
<%_ } _%>
|
|
9
16
|
}
|
|
10
17
|
}
|
|
11
18
|
|
|
@@ -11,6 +11,12 @@ terraform {
|
|
|
11
11
|
source = "hashicorp/external"
|
|
12
12
|
version = "<%- externalProviderVersion %>"
|
|
13
13
|
}
|
|
14
|
+
<%_ } _%>
|
|
15
|
+
<%_ if (protocol === 'mcp') { _%>
|
|
16
|
+
null = {
|
|
17
|
+
source = "hashicorp/null"
|
|
18
|
+
version = "<%- nullProviderVersion %>"
|
|
19
|
+
}
|
|
14
20
|
<%_ } _%>
|
|
15
21
|
time = {
|
|
16
22
|
source = "hashicorp/time"
|
|
@@ -76,6 +82,8 @@ locals {
|
|
|
76
82
|
<%_ if (cedarPolicy) { _%>
|
|
77
83
|
policies_dir = "${path.module}/../../../../../../../<%- projectDirectory %>/policies"
|
|
78
84
|
<%_ } _%>
|
|
85
|
+
|
|
86
|
+
gateway_waf_log_group_name = var.enable_waf ? "aws-waf-logs-<%- nameKebabCase %>-${random_id.unique_suffix.hex}" : null
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
resource "random_id" "unique_suffix" {
|
|
@@ -320,14 +328,61 @@ resource "aws_wafv2_web_acl_association" "gateway_waf" {
|
|
|
320
328
|
web_acl_arn = aws_wafv2_web_acl.gateway_waf[0].arn
|
|
321
329
|
}
|
|
322
330
|
|
|
331
|
+
# KMS key for encrypting WAF request logs at rest
|
|
332
|
+
resource "aws_kms_key" "gateway_waf_logs" {
|
|
333
|
+
count = var.enable_waf ? 1 : 0
|
|
334
|
+
|
|
335
|
+
description = "<%- nameClassName %> gateway WAF log encryption"
|
|
336
|
+
deletion_window_in_days = 7
|
|
337
|
+
enable_key_rotation = true
|
|
338
|
+
|
|
339
|
+
policy = jsonencode({
|
|
340
|
+
Version = "2012-10-17"
|
|
341
|
+
Statement = [
|
|
342
|
+
{
|
|
343
|
+
Sid = "Enable IAM User Permissions"
|
|
344
|
+
Effect = "Allow"
|
|
345
|
+
Principal = { AWS = "arn:aws:iam::${local.aws_account_id}:root" }
|
|
346
|
+
Action = "kms:*"
|
|
347
|
+
Resource = "*"
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
Sid = "Allow CloudWatch Logs"
|
|
351
|
+
Effect = "Allow"
|
|
352
|
+
Principal = { Service = "logs.${local.aws_region}.amazonaws.com" }
|
|
353
|
+
Action = [
|
|
354
|
+
"kms:Encrypt",
|
|
355
|
+
"kms:Decrypt",
|
|
356
|
+
"kms:ReEncrypt*",
|
|
357
|
+
"kms:GenerateDataKey*",
|
|
358
|
+
"kms:DescribeKey"
|
|
359
|
+
]
|
|
360
|
+
Resource = "*"
|
|
361
|
+
Condition = {
|
|
362
|
+
ArnEquals = {
|
|
363
|
+
"kms:EncryptionContext:aws:logs:arn" = "arn:aws:logs:${local.aws_region}:${local.aws_account_id}:log-group:${local.gateway_waf_log_group_name}"
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
]
|
|
368
|
+
})
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
resource "aws_kms_alias" "gateway_waf_logs" {
|
|
372
|
+
count = var.enable_waf ? 1 : 0
|
|
373
|
+
|
|
374
|
+
name = "alias/<%- nameKebabCase %>-${random_id.unique_suffix.hex}-waf-logs"
|
|
375
|
+
target_key_id = aws_kms_key.gateway_waf_logs[0].key_id
|
|
376
|
+
}
|
|
377
|
+
|
|
323
378
|
# WAF request logs. WAFv2 requires the `aws-waf-logs-` name prefix.
|
|
324
379
|
resource "aws_cloudwatch_log_group" "gateway_waf_logs" {
|
|
325
|
-
#checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
|
|
326
380
|
#checkov:skip=CKV_AWS_338:Log retention set to one year which is sufficient for WAF logs
|
|
327
381
|
count = var.enable_waf ? 1 : 0
|
|
328
382
|
|
|
329
|
-
name =
|
|
383
|
+
name = local.gateway_waf_log_group_name
|
|
330
384
|
retention_in_days = 365
|
|
385
|
+
kms_key_id = aws_kms_key.gateway_waf_logs[0].arn
|
|
331
386
|
}
|
|
332
387
|
|
|
333
388
|
resource "aws_wafv2_web_acl_logging_configuration" "gateway_waf_logging" {
|