@aws/nx-plugin 1.0.0-rc.31 → 1.0.0-rc.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-THIRD-PARTY +72 -70
- package/package.json +5 -5
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +15 -15
- package/src/infra/app/files/app/src/main.ts.template +1 -1
- package/src/infra/app/files/app/src/stages/application-stage.ts.template +1 -1
- package/src/infra/app/generator.js +3 -1
- package/src/infra/app/generator.js.map +1 -1
- package/src/open-api/ts-client/__snapshots__/generator.content-type.spec.ts.snap +64 -3
- package/src/open-api/ts-client/__snapshots__/generator.multipart.spec.ts.snap +280 -0
- package/src/open-api/ts-client/files/client.gen.ts.template +37 -2
- package/src/open-api/ts-client/generator.js +5 -1
- package/src/open-api/ts-client/generator.js.map +1 -1
- package/src/open-api/ts-hooks/files/options-proxy.gen.ts.template +2 -2
- package/src/open-api/ts-hooks/generator.js +5 -1
- package/src/open-api/ts-hooks/generator.js.map +1 -1
- package/src/open-api/utils/normalise.js +13 -6
- package/src/open-api/utils/normalise.js.map +1 -1
- package/src/open-api/utils/parser.js +12 -1
- package/src/open-api/utils/parser.js.map +1 -1
- package/src/open-api/utils/types.d.ts +4 -1
- package/src/open-api/utils/types.js.map +1 -1
- package/src/preset/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/preset/generator.d.ts +1 -1
- package/src/preset/generator.js +5 -2
- package/src/preset/generator.js.map +1 -1
- package/src/preset/schema.d.js.map +1 -1
- package/src/preset/schema.d.ts +2 -0
- package/src/preset/schema.json +6 -0
- package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +7 -7
- package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +8 -8
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +89 -3
- package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +426 -18
- package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +91 -5
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +283 -11
- package/src/smithy/ts/api/files/handler.ts.template +2 -2
- package/src/smithy/ts/api/files/local-server.ts.template +2 -2
- package/src/smithy/ts/api/files/operations/echo.ts.template +2 -2
- package/src/smithy/ts/api/files/service.ts.template +3 -3
- package/src/smithy/ts/api/generator.js +3 -1
- package/src/smithy/ts/api/generator.js.map +1 -1
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +426 -18
- package/src/trpc/backend/files/src/client/index.ts.template +1 -1
- package/src/trpc/backend/files/src/handler.ts.template +1 -1
- package/src/trpc/backend/files/src/index.ts.template +5 -5
- package/src/trpc/backend/files/src/init.ts.template +1 -1
- package/src/trpc/backend/files/src/local-server.ts.template +1 -1
- package/src/trpc/backend/files/src/middleware/index.ts.template +7 -7
- package/src/trpc/backend/files/src/procedures/echo.ts.template +2 -2
- package/src/trpc/backend/files/src/router.ts.template +2 -2
- package/src/trpc/backend/files/src/schema/index.ts.template +1 -1
- package/src/trpc/backend/generator.js +3 -1
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +89 -3
- package/src/ts/agent/a2a-connection/files/agent-connection/app/__targetAgentKebabCase__-client-strands.ts.template +2 -2
- package/src/ts/agent/a2a-connection/generator.js +3 -1
- package/src/ts/agent/a2a-connection/generator.js.map +1 -1
- package/src/ts/agent/files/a2a/index.ts.template +1 -1
- package/src/ts/agent/files/ag-ui/index.ts.template +1 -1
- package/src/ts/agent/files/http/client.ts.template +2 -2
- package/src/ts/agent/files/http/index.ts.template +2 -2
- package/src/ts/agent/files/http/router.ts.template +3 -3
- package/src/ts/agent/gateway-connection/files/agent-connection/app/__gatewayKebabCase__-client-strands.ts.template +2 -2
- package/src/ts/agent/gateway-connection/generator.js +3 -1
- package/src/ts/agent/gateway-connection/generator.js.map +1 -1
- package/src/ts/agent/generator.js +5 -2
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/files/agent-connection/app/__mcpServerKebabCase__-client-strands.ts.template +2 -2
- package/src/ts/agent/mcp-connection/generator.js +3 -1
- package/src/ts/agent/mcp-connection/generator.js.map +1 -1
- package/src/ts/astro-docs/files/translation/scripts/translate.ts.template +3 -2
- package/src/ts/astro-docs/generator.js +2 -0
- package/src/ts/astro-docs/generator.js.map +1 -1
- package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/dynamodb/files/src/client.ts.template +5 -2
- package/src/ts/dynamodb/files/src/entities/example.ts.template +1 -1
- package/src/ts/dynamodb/files/src/entities/index.ts.template +1 -1
- package/src/ts/dynamodb/files/src/index.ts.template +2 -2
- package/src/ts/dynamodb/generator.js +3 -1
- package/src/ts/dynamodb/generator.js.map +1 -1
- package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/lib/generator.js +7 -1
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/lib/ts-project-utils.js +19 -4
- package/src/ts/lib/ts-project-utils.js.map +1 -1
- package/src/ts/lib/types.d.ts +6 -0
- package/src/ts/lib/types.js.map +1 -1
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +94 -31
- package/src/ts/mcp-server/generator.js +11 -22
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/nx-generator/files/local/generator.ts.template +2 -2
- package/src/ts/nx-generator/files/nx-plugin-for-aws/generator/generator.ts.template +2 -2
- package/src/ts/nx-generator/generator.js +5 -2
- package/src/ts/nx-generator/generator.js.map +1 -1
- package/src/ts/nx-plugin/files/mcp-server/server.ts.template +5 -5
- package/src/ts/nx-plugin/files/mcp-server/tools/create-workspace-command.ts.template +2 -2
- package/src/ts/nx-plugin/files/mcp-server/tools/general-guidance.ts.template +1 -1
- package/src/ts/nx-plugin/files/mcp-server/tools/generator-guide.ts.template +2 -2
- package/src/ts/nx-plugin/files/mcp-server/tools/list-generators.ts.template +2 -2
- package/src/ts/nx-plugin/files/mcp-server/utils.ts.template +3 -3
- package/src/ts/nx-plugin/generator.js +3 -1
- package/src/ts/nx-plugin/generator.js.map +1 -1
- package/src/ts/nx-plugin/utils.js +7 -4
- package/src/ts/nx-plugin/utils.js.map +1 -1
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +4 -4
- package/src/ts/rdb/files/src/create-db-user-handler.ts.template +2 -2
- package/src/ts/rdb/files/src/index.ts.template +1 -1
- package/src/ts/rdb/files/src/migration-handler.ts.template +1 -1
- package/src/ts/rdb/files/src/prisma.ts.template +7 -4
- package/src/ts/rdb/generator.js +3 -1
- package/src/ts/rdb/generator.js.map +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +35 -35
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +2 -2
- package/src/utils/agent-chat/agent-chat.js +3 -1
- package/src/utils/agent-chat/agent-chat.js.map +1 -1
- package/src/utils/agent-chat/files/a2a/chat.ts.template +1 -1
- package/src/utils/agent-chat/files/ag-ui/chat.ts.template +1 -1
- package/src/utils/agent-chat/files/http-py/chat.ts.template +2 -2
- package/src/utils/agent-chat/files/http-ts/chat.ts.template +1 -1
- package/src/utils/agent-connection/agent-connection.js +4 -1
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client-config.ts.template +2 -2
- package/src/utils/agent-connection/files/core-auth/agentcore-fetch.ts.template +1 -1
- package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-transport.ts.template +2 -2
- package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-transport.ts.template +2 -2
- package/src/utils/agent-connection/files/core-shared/agentcore-transport.ts.template +1 -1
- package/src/utils/agent-connection/files/core-strands/a2a/agentcore-a2a-client-strands.ts.template +1 -1
- package/src/utils/agent-connection/files/core-strands/base/with-session-id-strands.ts.template +1 -1
- package/src/utils/agent-connection/files/core-strands/gateway/agentcore-gateway-mcp-client-strands.ts.template +1 -1
- package/src/utils/agent-connection/files/core-strands/mcp/agentcore-mcp-client-strands.ts.template +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.js +10 -3
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +3 -3
- package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +4 -4
- package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +1 -1
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +27 -0
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +60 -1
- package/src/utils/api-constructs/api-constructs.js +8 -2
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/files/cdk/app/apis/http/__apiNameKebabCase__.ts.template +8 -8
- package/src/utils/api-constructs/files/cdk/app/apis/rest/__apiNameKebabCase__.ts.template +8 -8
- package/src/utils/api-constructs/files/cdk/core/api/http/http-api.ts.template +3 -3
- package/src/utils/api-constructs/files/cdk/core/api/rest/api-gateway-account/index.js.template +32 -20
- package/src/utils/api-constructs/files/cdk/core/api/rest/api-gateway-account.ts.template +1 -1
- package/src/utils/api-constructs/files/cdk/core/api/rest/rest-api.ts.template +4 -4
- package/src/utils/api-constructs/files/cdk/core/api/trpc/trpc-utils.ts.template +1 -1
- package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +69 -1
- package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +69 -1
- package/src/utils/ast.js +16 -0
- package/src/utils/ast.js.map +1 -1
- package/src/utils/commands.d.ts +1 -1
- package/src/utils/commands.js +4 -1
- package/src/utils/commands.js.map +1 -1
- package/src/utils/dynamodb-constructs/dynamodb-constructs.js +9 -2
- package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -1
- package/src/utils/dynamodb-constructs/files/cdk/app/dynamodb/__nameKebabCase__.ts.template +3 -3
- package/src/utils/dynamodb-constructs/files/cdk/core/dynamodb.ts.template +1 -1
- package/src/utils/files/common/constructs/src/core/index.ts.template +4 -4
- package/src/utils/files/common/constructs/src/index.ts.template +2 -2
- package/src/utils/files/common/infra-config/src/index.ts.template +3 -3
- package/src/utils/files/common/infra-config/src/resolve-stage.ts.template +2 -2
- package/src/utils/files/common/infra-config/src/stages.config.ts.template +1 -1
- package/src/utils/files/common/scripts/src/infra/infra-deploy.ts.template +1 -1
- package/src/utils/files/common/scripts/src/infra/infra-destroy.ts.template +1 -1
- package/src/utils/files/common/scripts/src/infra/stage-credentials/run.ts.template +3 -3
- package/src/utils/files/common/shadcn/src/index.ts.template +2 -2
- package/src/utils/function-constructs/files/cdk/app/lambda-functions/__nameKebabCase__.ts.template +1 -1
- package/src/utils/function-constructs/function-constructs.js +3 -1
- package/src/utils/function-constructs/function-constructs.js.map +1 -1
- package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +2 -2
- package/src/utils/identity-constructs/identity-constructs.js +5 -1
- package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
- package/src/utils/module-format.d.ts +28 -0
- package/src/utils/module-format.js +28 -0
- package/src/utils/module-format.js.map +1 -0
- package/src/utils/rdb-constructs/files/cdk/app/dbs/__nameKebabCase__.ts.template +5 -5
- package/src/utils/rdb-constructs/files/cdk/core/rdb/aurora.ts.template +1 -1
- package/src/utils/rdb-constructs/rdb-constructs.js +9 -2
- package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
- package/src/utils/shared-constructs.js +3 -1
- package/src/utils/shared-constructs.js.map +1 -1
- package/src/utils/shared-infra-config.js +3 -1
- package/src/utils/shared-infra-config.js.map +1 -1
- package/src/utils/shared-infra-scripts.js +3 -1
- package/src/utils/shared-infra-scripts.js.map +1 -1
- package/src/utils/shared-shadcn.js +3 -1
- package/src/utils/shared-shadcn.js.map +1 -1
- package/src/utils/test.d.ts +2 -0
- package/src/utils/test.js +7 -1
- package/src/utils/test.js.map +1 -1
- package/src/utils/versions.d.ts +61 -61
- package/src/utils/versions.js +59 -59
- package/src/utils/versions.js.map +1 -1
- package/src/utils/website-constructs/files/cdk/app/static-websites/__websiteNameKebabCase__.ts.template +2 -2
- package/src/utils/website-constructs/files/cdk/core/static-website.ts.template +2 -2
- package/src/utils/website-constructs/website-constructs.js +9 -2
- package/src/utils/website-constructs/website-constructs.js.map +1 -1
|
@@ -70,6 +70,30 @@ variable "additional_iam_policy_statements" {
|
|
|
70
70
|
default = []
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
# VPC Configuration (optional)
|
|
74
|
+
variable "enable_vpc" {
|
|
75
|
+
description = "Run the agent core runtime inside a VPC. Set alongside vpc_id/subnet_ids."
|
|
76
|
+
type = bool
|
|
77
|
+
default = false
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
variable "vpc_id" {
|
|
81
|
+
description = "VPC ID to run the agent core runtime in. Required when enable_vpc is true."
|
|
82
|
+
type = string
|
|
83
|
+
default = null
|
|
84
|
+
|
|
85
|
+
validation {
|
|
86
|
+
condition = !var.enable_vpc || (var.vpc_id != null && var.subnet_ids != null)
|
|
87
|
+
error_message = "vpc_id and subnet_ids must be set when enable_vpc is true."
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
variable "subnet_ids" {
|
|
92
|
+
description = "Subnet IDs to run the agent core runtime in. Required when enable_vpc is true."
|
|
93
|
+
type = list(string)
|
|
94
|
+
default = null
|
|
95
|
+
}
|
|
96
|
+
|
|
73
97
|
variable "tags" {
|
|
74
98
|
description = "Tags to apply to resources"
|
|
75
99
|
type = map(string)
|
|
@@ -305,6 +329,28 @@ resource "null_resource" "docker_publish" {
|
|
|
305
329
|
depends_on = [aws_ecr_repository_policy.agent_core_ecr_policy]
|
|
306
330
|
}
|
|
307
331
|
|
|
332
|
+
# Security group for the agent core runtime, used when running inside a VPC
|
|
333
|
+
resource "aws_security_group" "agent_core_runtime" {
|
|
334
|
+
count = var.enable_vpc ? 1 : 0
|
|
335
|
+
|
|
336
|
+
#checkov:skip=CKV2_AWS_5:Attached to the runtime via network_configuration; Checkov cannot resolve this reference
|
|
337
|
+
name_prefix = "${var.agent_runtime_name}-runtime-"
|
|
338
|
+
description = "Security group for the ${var.agent_runtime_name} agent core runtime"
|
|
339
|
+
vpc_id = var.vpc_id
|
|
340
|
+
tags = var.tags
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
resource "aws_vpc_security_group_egress_rule" "agent_core_runtime_https" {
|
|
344
|
+
count = var.enable_vpc ? 1 : 0
|
|
345
|
+
|
|
346
|
+
security_group_id = aws_security_group.agent_core_runtime[0].id
|
|
347
|
+
cidr_ipv4 = "0.0.0.0/0"
|
|
348
|
+
from_port = 443
|
|
349
|
+
to_port = 443
|
|
350
|
+
ip_protocol = "tcp"
|
|
351
|
+
description = "Allow outbound HTTPS to AWS service endpoints"
|
|
352
|
+
}
|
|
353
|
+
|
|
308
354
|
# Bedrock AgentCore Agent Runtime
|
|
309
355
|
resource "aws_bedrockagentcore_agent_runtime" "agent_runtime" {
|
|
310
356
|
agent_runtime_name = "${var.agent_runtime_name}_${random_id.unique_suffix.hex}"
|
|
@@ -331,7 +377,15 @@ resource "aws_bedrockagentcore_agent_runtime" "agent_runtime" {
|
|
|
331
377
|
}
|
|
332
378
|
|
|
333
379
|
network_configuration {
|
|
334
|
-
network_mode = "PUBLIC"
|
|
380
|
+
network_mode = var.enable_vpc ? "VPC" : "PUBLIC"
|
|
381
|
+
|
|
382
|
+
dynamic "network_mode_config" {
|
|
383
|
+
for_each = var.enable_vpc ? [1] : []
|
|
384
|
+
content {
|
|
385
|
+
security_groups = [aws_security_group.agent_core_runtime[0].id]
|
|
386
|
+
subnets = var.subnet_ids
|
|
387
|
+
}
|
|
388
|
+
}
|
|
335
389
|
}
|
|
336
390
|
|
|
337
391
|
protocol_configuration {
|
|
@@ -433,3 +487,8 @@ output "agent_runtime_version" {
|
|
|
433
487
|
description = "Version of the Bedrock Agent Core runtime"
|
|
434
488
|
value = aws_bedrockagentcore_agent_runtime.agent_runtime.agent_runtime_version
|
|
435
489
|
}
|
|
490
|
+
|
|
491
|
+
output "security_group_id" {
|
|
492
|
+
description = "Security group ID of the agent core runtime, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true."
|
|
493
|
+
value = var.enable_vpc ? aws_security_group.agent_core_runtime[0].id : null
|
|
494
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/ import { generateFiles, joinPathFragments, OverwriteStrategy, updateJson } from "@nx/devkit";
|
|
5
5
|
import { addStarExport } from "../ast.js";
|
|
6
|
+
import { esmVars } from "../module-format.js";
|
|
6
7
|
import { addDependencyToTargetIfNotPresent } from "../nx.js";
|
|
7
8
|
import { PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, SHARED_TERRAFORM_DIR } from "../shared-constructs-constants.js";
|
|
8
9
|
import { PY_VERSIONS, terraformProviderVersions } from "../versions.js";
|
|
@@ -23,7 +24,9 @@ export const addApiGatewayInfra = async (tree, options)=>{
|
|
|
23
24
|
* Add an API CDK construct, and update the Runtime Config type to export its url
|
|
24
25
|
*/ const addApiGatewayCdkConstructs = async (tree, options)=>{
|
|
25
26
|
const generateCoreApiFile = (name)=>{
|
|
26
|
-
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'cdk', 'core', 'api', name), joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'src', 'core', 'api'), {
|
|
27
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'cdk', 'core', 'api', name), joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'src', 'core', 'api'), {
|
|
28
|
+
...esmVars(tree)
|
|
29
|
+
}, {
|
|
27
30
|
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
28
31
|
});
|
|
29
32
|
};
|
|
@@ -34,7 +37,10 @@ export const addApiGatewayInfra = async (tree, options)=>{
|
|
|
34
37
|
generateCoreApiFile('trpc');
|
|
35
38
|
}
|
|
36
39
|
// Generate app specific CDK construct
|
|
37
|
-
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'cdk', 'app', 'apis', options.constructType), joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'src', 'app', 'apis'),
|
|
40
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'cdk', 'app', 'apis', options.constructType), joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'src', 'app', 'apis'), {
|
|
41
|
+
...options,
|
|
42
|
+
...esmVars(tree)
|
|
43
|
+
}, {
|
|
38
44
|
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
39
45
|
});
|
|
40
46
|
// Export app specific CDK construct
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/api-constructs/api-constructs.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 ProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport { addStarExport } from '../ast';\nimport type { Iac } from '../iac';\nimport { addDependencyToTargetIfNotPresent } from '../nx';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../shared-constructs-constants';\nimport { PY_VERSIONS, terraformProviderVersions } from '../versions';\n\ninterface BackendOptions {\n type: 'trpc' | 'fastapi' | 'smithy';\n integrationPattern: 'isolated' | 'shared';\n}\n\nexport interface TrpcBackendOptions extends BackendOptions {\n type: 'trpc';\n projectAlias: string;\n bundleOutputDir: string;\n authorizerBundleOutputDir?: string;\n}\n\nexport interface FastApiBackendOptions extends BackendOptions {\n type: 'fastapi';\n moduleName: string;\n bundleOutputDir: string;\n}\n\nexport interface SmithyBackendOptions extends BackendOptions {\n type: 'smithy';\n bundleOutputDir: string;\n authorizerBundleOutputDir?: string;\n}\n\nexport interface AddApiGatewayConstructOptions {\n apiProjectName: string;\n apiNameClassName: string;\n apiNameKebabCase: string;\n constructType: 'http' | 'rest';\n backend: TrpcBackendOptions | FastApiBackendOptions | SmithyBackendOptions;\n auth: 'iam' | 'cognito' | 'custom';\n}\n\nexport const addApiGatewayInfra = async (\n tree: Tree,\n options: AddApiGatewayConstructOptions & { iac: Iac },\n) => {\n if (options.iac === 'cdk') {\n await addApiGatewayCdkConstructs(tree, options);\n } else if (options.iac === 'terraform') {\n addApiGatewayTerraformModules(tree, options);\n } else {\n throw new Error(`Unsupported iac ${options.iac}`);\n }\n\n updateJson(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR,\n 'project.json',\n ),\n (config: ProjectConfiguration) => {\n addDependencyToTargetIfNotPresent(\n config,\n 'build',\n `${options.apiProjectName}:build`,\n );\n return config;\n },\n );\n};\n\n/**\n * Add an API CDK construct, and update the Runtime Config type to export its url\n */\nconst addApiGatewayCdkConstructs = async (\n tree: Tree,\n options: AddApiGatewayConstructOptions,\n) => {\n const generateCoreApiFile = (name: string) => {\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'core',\n 'api',\n name,\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'api',\n ),\n {},\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n };\n\n // Generate relevant core CDK construct and utilities\n generateCoreApiFile(options.constructType);\n generateCoreApiFile('utils');\n if (options.backend.type === 'trpc') {\n generateCoreApiFile('trpc');\n }\n\n // Generate app specific CDK construct\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'app',\n 'apis',\n options.constructType,\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'apis',\n ),\n options,\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Export app specific CDK construct\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'apis',\n 'index.ts',\n ),\n `./${options.apiNameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n './apis/index.js',\n );\n};\n\n/**\n * Add an API terraform module, and update the Runtime Config type to export its url\n */\nconst addApiGatewayTerraformModules = (\n tree: Tree,\n options: AddApiGatewayConstructOptions,\n) => {\n // Generate core terraform module\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'core',\n 'api',\n options.constructType,\n ),\n joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'core', 'api'),\n { boto3Version: PY_VERSIONS.boto3, ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Generate app specific terraform module\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'apis',\n options.constructType,\n ),\n joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'app', 'apis'),\n { ...options, ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateJson","addStarExport","addDependencyToTargetIfNotPresent","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","PY_VERSIONS","terraformProviderVersions","addApiGatewayInfra","tree","options","iac","addApiGatewayCdkConstructs","addApiGatewayTerraformModules","Error","config","apiProjectName","generateCoreApiFile","name","dirname","overwriteStrategy","KeepExisting","constructType","backend","type","apiNameKebabCase","boto3Version","boto3"],"mappings":"AAAA;;;CAGC,GACD,SACEA,aAAa,EACbC,iBAAiB,EACjBC,iBAAiB,EAGjBC,UAAU,QACL,aAAa;AACpB,SAASC,aAAa,QAAQ,YAAS;AAEvC,SAASC,iCAAiC,QAAQ,WAAQ;AAC1D,SACEC,YAAY,EACZC,qBAAqB,EACrBC,oBAAoB,QACf,oCAAiC;AACxC,SAASC,WAAW,EAAEC,yBAAyB,QAAQ,iBAAc;AAmCrE,OAAO,MAAMC,qBAAqB,OAChCC,MACAC;IAEA,IAAIA,QAAQC,GAAG,KAAK,OAAO;QACzB,MAAMC,2BAA2BH,MAAMC;IACzC,OAAO,IAAIA,QAAQC,GAAG,KAAK,aAAa;QACtCE,8BAA8BJ,MAAMC;IACtC,OAAO;QACL,MAAM,IAAII,MAAM,CAAC,gBAAgB,EAAEJ,QAAQC,GAAG,EAAE;IAClD;
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/api-constructs/api-constructs.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 ProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport { addStarExport } from '../ast';\nimport type { Iac } from '../iac';\nimport { esmVars } from '../module-format';\nimport { addDependencyToTargetIfNotPresent } from '../nx';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../shared-constructs-constants';\nimport { PY_VERSIONS, terraformProviderVersions } from '../versions';\n\ninterface BackendOptions {\n type: 'trpc' | 'fastapi' | 'smithy';\n integrationPattern: 'isolated' | 'shared';\n}\n\nexport interface TrpcBackendOptions extends BackendOptions {\n type: 'trpc';\n projectAlias: string;\n bundleOutputDir: string;\n authorizerBundleOutputDir?: string;\n}\n\nexport interface FastApiBackendOptions extends BackendOptions {\n type: 'fastapi';\n moduleName: string;\n bundleOutputDir: string;\n}\n\nexport interface SmithyBackendOptions extends BackendOptions {\n type: 'smithy';\n bundleOutputDir: string;\n authorizerBundleOutputDir?: string;\n}\n\nexport interface AddApiGatewayConstructOptions {\n apiProjectName: string;\n apiNameClassName: string;\n apiNameKebabCase: string;\n constructType: 'http' | 'rest';\n backend: TrpcBackendOptions | FastApiBackendOptions | SmithyBackendOptions;\n auth: 'iam' | 'cognito' | 'custom';\n}\n\nexport const addApiGatewayInfra = async (\n tree: Tree,\n options: AddApiGatewayConstructOptions & { iac: Iac },\n) => {\n if (options.iac === 'cdk') {\n await addApiGatewayCdkConstructs(tree, options);\n } else if (options.iac === 'terraform') {\n addApiGatewayTerraformModules(tree, options);\n } else {\n throw new Error(`Unsupported iac ${options.iac}`);\n }\n\n updateJson(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR,\n 'project.json',\n ),\n (config: ProjectConfiguration) => {\n addDependencyToTargetIfNotPresent(\n config,\n 'build',\n `${options.apiProjectName}:build`,\n );\n return config;\n },\n );\n};\n\n/**\n * Add an API CDK construct, and update the Runtime Config type to export its url\n */\nconst addApiGatewayCdkConstructs = async (\n tree: Tree,\n options: AddApiGatewayConstructOptions,\n) => {\n const generateCoreApiFile = (name: string) => {\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'core',\n 'api',\n name,\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'api',\n ),\n { ...esmVars(tree) },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n };\n\n // Generate relevant core CDK construct and utilities\n generateCoreApiFile(options.constructType);\n generateCoreApiFile('utils');\n if (options.backend.type === 'trpc') {\n generateCoreApiFile('trpc');\n }\n\n // Generate app specific CDK construct\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'app',\n 'apis',\n options.constructType,\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'apis',\n ),\n { ...options, ...esmVars(tree) },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Export app specific CDK construct\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'apis',\n 'index.ts',\n ),\n `./${options.apiNameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n './apis/index.js',\n );\n};\n\n/**\n * Add an API terraform module, and update the Runtime Config type to export its url\n */\nconst addApiGatewayTerraformModules = (\n tree: Tree,\n options: AddApiGatewayConstructOptions,\n) => {\n // Generate core terraform module\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'core',\n 'api',\n options.constructType,\n ),\n joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'core', 'api'),\n { boto3Version: PY_VERSIONS.boto3, ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Generate app specific terraform module\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'apis',\n options.constructType,\n ),\n joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'app', 'apis'),\n { ...options, ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateJson","addStarExport","esmVars","addDependencyToTargetIfNotPresent","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","PY_VERSIONS","terraformProviderVersions","addApiGatewayInfra","tree","options","iac","addApiGatewayCdkConstructs","addApiGatewayTerraformModules","Error","config","apiProjectName","generateCoreApiFile","name","dirname","overwriteStrategy","KeepExisting","constructType","backend","type","apiNameKebabCase","boto3Version","boto3"],"mappings":"AAAA;;;CAGC,GACD,SACEA,aAAa,EACbC,iBAAiB,EACjBC,iBAAiB,EAGjBC,UAAU,QACL,aAAa;AACpB,SAASC,aAAa,QAAQ,YAAS;AAEvC,SAASC,OAAO,QAAQ,sBAAmB;AAC3C,SAASC,iCAAiC,QAAQ,WAAQ;AAC1D,SACEC,YAAY,EACZC,qBAAqB,EACrBC,oBAAoB,QACf,oCAAiC;AACxC,SAASC,WAAW,EAAEC,yBAAyB,QAAQ,iBAAc;AAmCrE,OAAO,MAAMC,qBAAqB,OAChCC,MACAC;IAEA,IAAIA,QAAQC,GAAG,KAAK,OAAO;QACzB,MAAMC,2BAA2BH,MAAMC;IACzC,OAAO,IAAIA,QAAQC,GAAG,KAAK,aAAa;QACtCE,8BAA8BJ,MAAMC;IACtC,OAAO;QACL,MAAM,IAAII,MAAM,CAAC,gBAAgB,EAAEJ,QAAQC,GAAG,EAAE;IAClD;IAEAZ,WACEU,MACAZ,kBACEM,cACAO,QAAQC,GAAG,KAAK,QAAQP,wBAAwBC,sBAChD,iBAEF,CAACU;QACCb,kCACEa,QACA,SACA,GAAGL,QAAQM,cAAc,CAAC,MAAM,CAAC;QAEnC,OAAOD;IACT;AAEJ,EAAE;AAEF;;CAEC,GACD,MAAMH,6BAA6B,OACjCH,MACAC;IAEA,MAAMO,sBAAsB,CAACC;QAC3BtB,cACEa,MACAZ,kBACE,YAAYsB,OAAO,EACnB,SACA,OACA,QACA,OACAD,OAEFrB,kBACEM,cACAC,uBACA,OACA,QACA,QAEF;YAAE,GAAGH,QAAQQ,KAAK;QAAC,GACnB;YACEW,mBAAmBtB,kBAAkBuB,YAAY;QACnD;IAEJ;IAEA,qDAAqD;IACrDJ,oBAAoBP,QAAQY,aAAa;IACzCL,oBAAoB;IACpB,IAAIP,QAAQa,OAAO,CAACC,IAAI,KAAK,QAAQ;QACnCP,oBAAoB;IACtB;IAEA,sCAAsC;IACtCrB,cACEa,MACAZ,kBACE,YAAYsB,OAAO,EACnB,SACA,OACA,OACA,QACAT,QAAQY,aAAa,GAEvBzB,kBACEM,cACAC,uBACA,OACA,OACA,SAEF;QAAE,GAAGM,OAAO;QAAE,GAAGT,QAAQQ,KAAK;IAAC,GAC/B;QACEW,mBAAmBtB,kBAAkBuB,YAAY;IACnD;IAGF,oCAAoC;IACpC,MAAMrB,cACJS,MACAZ,kBACEM,cACAC,uBACA,OACA,OACA,QACA,aAEF,CAAC,EAAE,EAAEM,QAAQe,gBAAgB,CAAC,GAAG,CAAC;IAEpC,MAAMzB,cACJS,MACAZ,kBACEM,cACAC,uBACA,OACA,OACA,aAEF;AAEJ;AAEA;;CAEC,GACD,MAAMS,gCAAgC,CACpCJ,MACAC;IAEA,iCAAiC;IACjCd,cACEa,MACAZ,kBACE,YAAYsB,OAAO,EACnB,SACA,aACA,QACA,OACAT,QAAQY,aAAa,GAEvBzB,kBAAkBM,cAAcE,sBAAsB,OAAO,QAAQ,QACrE;QAAEqB,cAAcpB,YAAYqB,KAAK;QAAE,GAAGpB,2BAA2B;IAAC,GAClE;QACEa,mBAAmBtB,kBAAkBuB,YAAY;IACnD;IAGF,yCAAyC;IACzCzB,cACEa,MACAZ,kBACE,YAAYsB,OAAO,EACnB,SACA,aACA,OACA,QACAT,QAAQY,aAAa,GAEvBzB,kBAAkBM,cAAcE,sBAAsB,OAAO,OAAO,SACpE;QAAE,GAAGK,OAAO;QAAE,GAAGH,2BAA2B;IAAC,GAC7C;QACEa,mBAAmBtB,kBAAkBuB,YAAY;IACnD;AAEJ"}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
<%_ } _%>
|
|
14
14
|
} from 'aws-cdk-lib/aws-lambda';
|
|
15
15
|
import { Duration<%_ if (backend.type === 'fastapi') { _%>, Stack<%_ } _%> } from 'aws-cdk-lib';
|
|
16
|
-
import { RuntimeConfig } from '../../core/runtime-config
|
|
16
|
+
import { RuntimeConfig } from '../../core/runtime-config<% if (esm) { %>.js<% } %>';
|
|
17
17
|
import {
|
|
18
18
|
CorsHttpMethod,
|
|
19
19
|
CfnApi,
|
|
@@ -41,10 +41,10 @@ import {
|
|
|
41
41
|
ApiIntegrations,
|
|
42
42
|
HttpApiIntegration,
|
|
43
43
|
IntegrationBuilder,
|
|
44
|
-
} from '../../core/api/utils
|
|
45
|
-
import { HttpApi } from '../../core/api/http-api
|
|
44
|
+
} from '../../core/api/utils<% if (esm) { %>.js<% } %>';
|
|
45
|
+
import { HttpApi } from '../../core/api/http-api<% if (esm) { %>.js<% } %>';
|
|
46
46
|
<%_ if (backend.type === 'trpc') { _%>
|
|
47
|
-
import { Procedures, routerToOperations } from '../../core/api/trpc-utils
|
|
47
|
+
import { Procedures, routerToOperations } from '../../core/api/trpc-utils<% if (esm) { %>.js<% } %>';
|
|
48
48
|
import { AppRouter, appRouter } from '<%= backend.projectAlias %>';
|
|
49
49
|
|
|
50
50
|
// String union type for all API operation names
|
|
@@ -116,7 +116,7 @@ export class <%= apiNameClassName %><
|
|
|
116
116
|
url.fileURLToPath(
|
|
117
117
|
new URL(
|
|
118
118
|
'../../../../../../<%- backend.bundleOutputDir %>',
|
|
119
|
-
import.meta.url
|
|
119
|
+
<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>,
|
|
120
120
|
),
|
|
121
121
|
),
|
|
122
122
|
),
|
|
@@ -127,7 +127,7 @@ export class <%= apiNameClassName %><
|
|
|
127
127
|
url.fileURLToPath(
|
|
128
128
|
new URL(
|
|
129
129
|
'../../../../../../<%- backend.bundleOutputDir %>',
|
|
130
|
-
import.meta.url
|
|
130
|
+
<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>,
|
|
131
131
|
),
|
|
132
132
|
),
|
|
133
133
|
),
|
|
@@ -184,7 +184,7 @@ export class <%= apiNameClassName %><
|
|
|
184
184
|
url.fileURLToPath(
|
|
185
185
|
new URL(
|
|
186
186
|
'../../../../../../<%- backend.authorizerBundleOutputDir %>',
|
|
187
|
-
import.meta.url
|
|
187
|
+
<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>,
|
|
188
188
|
),
|
|
189
189
|
),
|
|
190
190
|
),
|
|
@@ -195,7 +195,7 @@ export class <%= apiNameClassName %><
|
|
|
195
195
|
url.fileURLToPath(
|
|
196
196
|
new URL(
|
|
197
197
|
'../../../../../../<%- backend.bundleOutputDir %>',
|
|
198
|
-
import.meta.url
|
|
198
|
+
<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>,
|
|
199
199
|
),
|
|
200
200
|
),
|
|
201
201
|
),
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
SnapStartConf,
|
|
13
13
|
<%_ } _%>
|
|
14
14
|
} from 'aws-cdk-lib/aws-lambda';
|
|
15
|
-
import { RuntimeConfig } from '../../core/runtime-config
|
|
15
|
+
import { RuntimeConfig } from '../../core/runtime-config<% if (esm) { %>.js<% } %>';
|
|
16
16
|
import {
|
|
17
17
|
AuthorizationType,
|
|
18
18
|
LambdaIntegration,
|
|
@@ -44,10 +44,10 @@ import {
|
|
|
44
44
|
ApiIntegrations,
|
|
45
45
|
IntegrationBuilder,
|
|
46
46
|
RestApiIntegration,
|
|
47
|
-
} from '../../core/api/utils
|
|
48
|
-
import { AddCorsPreflightAspect, RestApi } from '../../core/api/rest-api
|
|
47
|
+
} from '../../core/api/utils<% if (esm) { %>.js<% } %>';
|
|
48
|
+
import { AddCorsPreflightAspect, RestApi } from '../../core/api/rest-api<% if (esm) { %>.js<% } %>';
|
|
49
49
|
<%_ if (backend.type === 'trpc') { _%>
|
|
50
|
-
import { Procedures, routerToOperations } from '../../core/api/trpc-utils
|
|
50
|
+
import { Procedures, routerToOperations } from '../../core/api/trpc-utils<% if (esm) { %>.js<% } %>';
|
|
51
51
|
import { AppRouter, appRouter } from '<%= backend.projectAlias %>';
|
|
52
52
|
|
|
53
53
|
// String union type for all API operation names
|
|
@@ -126,7 +126,7 @@ export class <%= apiNameClassName %><
|
|
|
126
126
|
url.fileURLToPath(
|
|
127
127
|
new URL(
|
|
128
128
|
'../../../../../../<%- backend.bundleOutputDir %>',
|
|
129
|
-
import.meta.url
|
|
129
|
+
<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>,
|
|
130
130
|
),
|
|
131
131
|
),
|
|
132
132
|
),
|
|
@@ -137,7 +137,7 @@ export class <%= apiNameClassName %><
|
|
|
137
137
|
url.fileURLToPath(
|
|
138
138
|
new URL(
|
|
139
139
|
'../../../../../../<%- backend.bundleOutputDir %>',
|
|
140
|
-
import.meta.url
|
|
140
|
+
<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>,
|
|
141
141
|
),
|
|
142
142
|
),
|
|
143
143
|
),
|
|
@@ -204,7 +204,7 @@ export class <%= apiNameClassName %><
|
|
|
204
204
|
url.fileURLToPath(
|
|
205
205
|
new URL(
|
|
206
206
|
'../../../../../../<%- backend.authorizerBundleOutputDir %>',
|
|
207
|
-
import.meta.url
|
|
207
|
+
<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>,
|
|
208
208
|
),
|
|
209
209
|
),
|
|
210
210
|
),
|
|
@@ -215,7 +215,7 @@ export class <%= apiNameClassName %><
|
|
|
215
215
|
url.fileURLToPath(
|
|
216
216
|
new URL(
|
|
217
217
|
'../../../../../../<%- backend.bundleOutputDir %>',
|
|
218
|
-
import.meta.url
|
|
218
|
+
<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>,
|
|
219
219
|
),
|
|
220
220
|
),
|
|
221
221
|
),
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Construct } from 'constructs';
|
|
2
|
-
import { RuntimeConfig } from '../runtime-config
|
|
2
|
+
import { RuntimeConfig } from '../runtime-config<% if (esm) { %>.js<% } %>';
|
|
3
3
|
import {
|
|
4
4
|
ApiIntegrations,
|
|
5
5
|
HttpApiIntegration,
|
|
6
6
|
OperationDetails,
|
|
7
|
-
} from './utils
|
|
7
|
+
} from './utils<% if (esm) { %>.js<% } %>';
|
|
8
8
|
import { CfnOutput, Stack } from 'aws-cdk-lib';
|
|
9
9
|
import {
|
|
10
10
|
HttpApi as _HttpApi,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import { LogGroup } from 'aws-cdk-lib/aws-logs';
|
|
18
18
|
import { Key } from 'aws-cdk-lib/aws-kms';
|
|
19
19
|
import { ServicePrincipal } from 'aws-cdk-lib/aws-iam';
|
|
20
|
-
import { suppressRules } from '../checkov
|
|
20
|
+
import { suppressRules } from '../checkov<% if (esm) { %>.js<% } %>';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Properties for creating an HttpApi construct.
|
package/src/utils/api-constructs/files/cdk/core/api/rest/api-gateway-account/index.js.template
CHANGED
|
@@ -16,32 +16,23 @@ const iam = new IAMClient();
|
|
|
16
16
|
|
|
17
17
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
18
18
|
|
|
19
|
-
const hasLiveRole = async () => {
|
|
20
|
-
const { cloudwatchRoleArn } = await apigw.send(new GetAccountCommand({}));
|
|
21
|
-
if (!cloudwatchRoleArn) return false;
|
|
22
|
-
try {
|
|
23
|
-
await iam.send(
|
|
24
|
-
new GetRoleCommand({ RoleName: cloudwatchRoleArn.split('/').pop() }),
|
|
25
|
-
);
|
|
26
|
-
return true;
|
|
27
|
-
} catch (e) {
|
|
28
|
-
if (e.name === 'NoSuchEntityException') return false;
|
|
29
|
-
throw e;
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
|
|
33
19
|
const RETRYABLE = ['BadRequestException', 'TooManyRequestsException'];
|
|
34
20
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
21
|
+
// Throttling may surface as a bare 429 with no modeled error code, so check
|
|
22
|
+
// response metadata as well as error names
|
|
23
|
+
const isRetryable = (e) =>
|
|
24
|
+
RETRYABLE.includes(e.name) ||
|
|
25
|
+
e.$metadata?.httpStatusCode === 429 ||
|
|
26
|
+
e.$retryable?.throttling === true;
|
|
27
|
+
|
|
28
|
+
// Retry while the freshly created role propagates through IAM, and on
|
|
29
|
+
// throttling of the account-level API (shared across concurrent deployments)
|
|
30
|
+
const send = async (command) => {
|
|
40
31
|
for (let attempt = 0; ; attempt++) {
|
|
41
32
|
try {
|
|
42
33
|
return await apigw.send(command);
|
|
43
34
|
} catch (e) {
|
|
44
|
-
if (
|
|
35
|
+
if (isRetryable(e) && attempt < 11) {
|
|
45
36
|
await sleep(5000);
|
|
46
37
|
} else {
|
|
47
38
|
throw e;
|
|
@@ -50,6 +41,27 @@ const setRole = async (value) => {
|
|
|
50
41
|
}
|
|
51
42
|
};
|
|
52
43
|
|
|
44
|
+
const hasLiveRole = async () => {
|
|
45
|
+
const { cloudwatchRoleArn } = await send(new GetAccountCommand({}));
|
|
46
|
+
if (!cloudwatchRoleArn) return false;
|
|
47
|
+
try {
|
|
48
|
+
await iam.send(
|
|
49
|
+
new GetRoleCommand({ RoleName: cloudwatchRoleArn.split('/').pop() }),
|
|
50
|
+
);
|
|
51
|
+
return true;
|
|
52
|
+
} catch (e) {
|
|
53
|
+
if (e.name === 'NoSuchEntityException') return false;
|
|
54
|
+
throw e;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const setRole = (value) =>
|
|
59
|
+
send(
|
|
60
|
+
new UpdateAccountCommand({
|
|
61
|
+
patchOperations: [{ op: 'replace', path: '/cloudwatchRoleArn', value }],
|
|
62
|
+
}),
|
|
63
|
+
);
|
|
64
|
+
|
|
53
65
|
exports.handler = async (event) => {
|
|
54
66
|
if (event.RequestType !== 'Delete' && !(await hasLiveRole())) {
|
|
55
67
|
await setRole(event.ResourceProperties.CloudWatchRoleArn);
|
|
@@ -50,7 +50,7 @@ export class ApiGatewayAccount extends Construct {
|
|
|
50
50
|
handler: 'index.handler',
|
|
51
51
|
timeout: Duration.minutes(2),
|
|
52
52
|
code: Code.fromAsset(
|
|
53
|
-
url.fileURLToPath(new URL('./api-gateway-account', import.meta.url)),
|
|
53
|
+
url.fileURLToPath(new URL('./api-gateway-account', <% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>)),
|
|
54
54
|
),
|
|
55
55
|
});
|
|
56
56
|
const { region } = Stack.of(this);
|
|
@@ -19,14 +19,14 @@ import {
|
|
|
19
19
|
import { LogGroup, RetentionDays } from 'aws-cdk-lib/aws-logs';
|
|
20
20
|
import { Key } from 'aws-cdk-lib/aws-kms';
|
|
21
21
|
import { ServicePrincipal } from 'aws-cdk-lib/aws-iam';
|
|
22
|
-
import { RuntimeConfig } from '../runtime-config
|
|
23
|
-
import { ApiGatewayAccount } from './api-gateway-account
|
|
22
|
+
import { RuntimeConfig } from '../runtime-config<% if (esm) { %>.js<% } %>';
|
|
23
|
+
import { ApiGatewayAccount } from './api-gateway-account<% if (esm) { %>.js<% } %>';
|
|
24
24
|
import {
|
|
25
25
|
ApiIntegrations,
|
|
26
26
|
OperationDetails,
|
|
27
27
|
RestApiIntegration,
|
|
28
|
-
} from './utils
|
|
29
|
-
import { suppressRules } from '../checkov
|
|
28
|
+
} from './utils<% if (esm) { %>.js<% } %>';
|
|
29
|
+
import { suppressRules } from '../checkov<% if (esm) { %>.js<% } %>';
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* Properties for creating a RestApi construct.
|
|
@@ -43,6 +43,30 @@ variable "asset_bucket_name" {
|
|
|
43
43
|
type = string
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
# VPC Configuration (optional)
|
|
47
|
+
variable "enable_vpc" {
|
|
48
|
+
description = "Deploy the Lambda function into a VPC. Set alongside vpc_id/subnet_ids."
|
|
49
|
+
type = bool
|
|
50
|
+
default = false
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
variable "vpc_id" {
|
|
54
|
+
description = "VPC ID to deploy the Lambda function into. Required when enable_vpc is true."
|
|
55
|
+
type = string
|
|
56
|
+
default = null
|
|
57
|
+
|
|
58
|
+
validation {
|
|
59
|
+
condition = !var.enable_vpc || (var.vpc_id != null && var.subnet_ids != null)
|
|
60
|
+
error_message = "vpc_id and subnet_ids must be set when enable_vpc is true."
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
variable "subnet_ids" {
|
|
65
|
+
description = "Subnet IDs to deploy the Lambda function into. Required when enable_vpc is true."
|
|
66
|
+
type = list(string)
|
|
67
|
+
default = null
|
|
68
|
+
}
|
|
69
|
+
|
|
46
70
|
# CORS Configuration (passed to core module)
|
|
47
71
|
variable "cors_allow_credentials" {
|
|
48
72
|
description = "Whether to allow credentials in CORS requests"
|
|
@@ -129,10 +153,32 @@ module "http_api" {
|
|
|
129
153
|
tags = var.tags
|
|
130
154
|
}
|
|
131
155
|
|
|
156
|
+
# Security group for the API Lambda function, used when deployed into a VPC
|
|
157
|
+
resource "aws_security_group" "api_lambda" {
|
|
158
|
+
count = var.enable_vpc ? 1 : 0
|
|
159
|
+
|
|
160
|
+
#checkov:skip=CKV2_AWS_5:Attached to api_lambda via vpc_config block; Checkov cannot resolve this reference
|
|
161
|
+
name_prefix = "<%- apiNameKebabCase %>-lambda-"
|
|
162
|
+
description = "Security group for the <%- apiNameClassName %> API Lambda function"
|
|
163
|
+
vpc_id = var.vpc_id
|
|
164
|
+
tags = var.tags
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
resource "aws_vpc_security_group_egress_rule" "api_lambda_https" {
|
|
168
|
+
count = var.enable_vpc ? 1 : 0
|
|
169
|
+
|
|
170
|
+
security_group_id = aws_security_group.api_lambda[0].id
|
|
171
|
+
cidr_ipv4 = "0.0.0.0/0"
|
|
172
|
+
from_port = 443
|
|
173
|
+
to_port = 443
|
|
174
|
+
ip_protocol = "tcp"
|
|
175
|
+
description = "Allow outbound HTTPS to AWS service endpoints"
|
|
176
|
+
}
|
|
177
|
+
|
|
132
178
|
# Lambda function
|
|
133
179
|
# This configures a single "router" lambda to serve all requests
|
|
134
180
|
resource "aws_lambda_function" "api_lambda" {
|
|
135
|
-
#checkov:skip=CKV_AWS_117:Lambda function
|
|
181
|
+
#checkov:skip=CKV_AWS_117:Lambda function is optionally deployed into a VPC via vpc_id/subnet_ids; not required for this use case
|
|
136
182
|
#checkov:skip=CKV_AWS_116:Dead Letter Queue not required for this simple API use case
|
|
137
183
|
#checkov:skip=CKV_AWS_272:Code signing not required for this use case
|
|
138
184
|
#checkov:skip=CKV_AWS_115:Concurrent execution limit not required for this use case
|
|
@@ -163,6 +209,14 @@ resource "aws_lambda_function" "api_lambda" {
|
|
|
163
209
|
mode = "Active"
|
|
164
210
|
}
|
|
165
211
|
|
|
212
|
+
dynamic "vpc_config" {
|
|
213
|
+
for_each = var.enable_vpc ? [1] : []
|
|
214
|
+
content {
|
|
215
|
+
subnet_ids = var.subnet_ids
|
|
216
|
+
security_group_ids = [aws_security_group.api_lambda[0].id]
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
166
220
|
<%_ if (backend.type === 'fastapi') { _%>
|
|
167
221
|
# Enable SnapStart for faster cold starts
|
|
168
222
|
snap_start {
|
|
@@ -181,6 +235,8 @@ resource "aws_lambda_function" "api_lambda" {
|
|
|
181
235
|
}
|
|
182
236
|
|
|
183
237
|
tags = var.tags
|
|
238
|
+
|
|
239
|
+
depends_on = [aws_iam_role_policy_attachment.lambda_vpc_access]
|
|
184
240
|
}
|
|
185
241
|
|
|
186
242
|
# IAM role for Lambda execution
|
|
@@ -215,6 +271,13 @@ resource "aws_iam_role_policy_attachment" "lambda_xray_execution" {
|
|
|
215
271
|
role = aws_iam_role.lambda_execution_role.name
|
|
216
272
|
}
|
|
217
273
|
|
|
274
|
+
# Attach VPC access policy to Lambda role when deployed into a VPC
|
|
275
|
+
resource "aws_iam_role_policy_attachment" "lambda_vpc_access" {
|
|
276
|
+
count = var.enable_vpc ? 1 : 0
|
|
277
|
+
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
|
|
278
|
+
role = aws_iam_role.lambda_execution_role.name
|
|
279
|
+
}
|
|
280
|
+
|
|
218
281
|
# Additional IAM policies for Lambda (if provided)
|
|
219
282
|
resource "aws_iam_role_policy" "lambda_additional_policies" {
|
|
220
283
|
count = length(var.additional_iam_policy_statements) > 0 ? 1 : 0
|
|
@@ -527,6 +590,11 @@ output "lambda_execution_role_name" {
|
|
|
527
590
|
value = aws_iam_role.lambda_execution_role.name
|
|
528
591
|
}
|
|
529
592
|
|
|
593
|
+
output "security_group_id" {
|
|
594
|
+
description = "Security group ID of the API Lambda function, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true."
|
|
595
|
+
value = var.enable_vpc ? aws_security_group.api_lambda[0].id : null
|
|
596
|
+
}
|
|
597
|
+
|
|
530
598
|
# Integration Outputs
|
|
531
599
|
output "integration_id" {
|
|
532
600
|
description = "ID of the Lambda integration"
|
|
@@ -43,6 +43,30 @@ variable "asset_bucket_name" {
|
|
|
43
43
|
type = string
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
# VPC Configuration (optional)
|
|
47
|
+
variable "enable_vpc" {
|
|
48
|
+
description = "Deploy the Lambda function into a VPC. Set alongside vpc_id/subnet_ids."
|
|
49
|
+
type = bool
|
|
50
|
+
default = false
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
variable "vpc_id" {
|
|
54
|
+
description = "VPC ID to deploy the Lambda function into. Required when enable_vpc is true."
|
|
55
|
+
type = string
|
|
56
|
+
default = null
|
|
57
|
+
|
|
58
|
+
validation {
|
|
59
|
+
condition = !var.enable_vpc || (var.vpc_id != null && var.subnet_ids != null)
|
|
60
|
+
error_message = "vpc_id and subnet_ids must be set when enable_vpc is true."
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
variable "subnet_ids" {
|
|
65
|
+
description = "Subnet IDs to deploy the Lambda function into. Required when enable_vpc is true."
|
|
66
|
+
type = list(string)
|
|
67
|
+
default = null
|
|
68
|
+
}
|
|
69
|
+
|
|
46
70
|
# CORS Configuration (passed to core module)
|
|
47
71
|
|
|
48
72
|
variable "cors_allow_headers" {
|
|
@@ -139,9 +163,31 @@ resource "aws_wafv2_web_acl_association" "api_waf_association" {
|
|
|
139
163
|
depends_on = [aws_api_gateway_stage.api_stage]
|
|
140
164
|
}
|
|
141
165
|
|
|
166
|
+
# Security group for the API Lambda function, used when deployed into a VPC
|
|
167
|
+
resource "aws_security_group" "api_lambda" {
|
|
168
|
+
count = var.enable_vpc ? 1 : 0
|
|
169
|
+
|
|
170
|
+
#checkov:skip=CKV2_AWS_5:Attached to api_lambda via vpc_config block; Checkov cannot resolve this reference
|
|
171
|
+
name_prefix = "<%- apiNameKebabCase %>-lambda-"
|
|
172
|
+
description = "Security group for the <%- apiNameClassName %> API Lambda function"
|
|
173
|
+
vpc_id = var.vpc_id
|
|
174
|
+
tags = var.tags
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
resource "aws_vpc_security_group_egress_rule" "api_lambda_https" {
|
|
178
|
+
count = var.enable_vpc ? 1 : 0
|
|
179
|
+
|
|
180
|
+
security_group_id = aws_security_group.api_lambda[0].id
|
|
181
|
+
cidr_ipv4 = "0.0.0.0/0"
|
|
182
|
+
from_port = 443
|
|
183
|
+
to_port = 443
|
|
184
|
+
ip_protocol = "tcp"
|
|
185
|
+
description = "Allow outbound HTTPS to AWS service endpoints"
|
|
186
|
+
}
|
|
187
|
+
|
|
142
188
|
# Lambda function
|
|
143
189
|
resource "aws_lambda_function" "api_lambda" {
|
|
144
|
-
#checkov:skip=CKV_AWS_117:Lambda function
|
|
190
|
+
#checkov:skip=CKV_AWS_117:Lambda function is optionally deployed into a VPC via vpc_id/subnet_ids; not required for this use case
|
|
145
191
|
#checkov:skip=CKV_AWS_116:Dead Letter Queue not required for this simple API use case
|
|
146
192
|
#checkov:skip=CKV_AWS_272:Code signing not required for this use case
|
|
147
193
|
#checkov:skip=CKV_AWS_115:Concurrent execution limit not required for this use case
|
|
@@ -172,6 +218,14 @@ resource "aws_lambda_function" "api_lambda" {
|
|
|
172
218
|
mode = "Active"
|
|
173
219
|
}
|
|
174
220
|
|
|
221
|
+
dynamic "vpc_config" {
|
|
222
|
+
for_each = var.enable_vpc ? [1] : []
|
|
223
|
+
content {
|
|
224
|
+
subnet_ids = var.subnet_ids
|
|
225
|
+
security_group_ids = [aws_security_group.api_lambda[0].id]
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
175
229
|
<%_ if (backend.type === 'fastapi') { _%>
|
|
176
230
|
# Enable SnapStart for faster cold starts
|
|
177
231
|
snap_start {
|
|
@@ -190,6 +244,8 @@ resource "aws_lambda_function" "api_lambda" {
|
|
|
190
244
|
}
|
|
191
245
|
|
|
192
246
|
tags = var.tags
|
|
247
|
+
|
|
248
|
+
depends_on = [aws_iam_role_policy_attachment.lambda_vpc_access]
|
|
193
249
|
}
|
|
194
250
|
|
|
195
251
|
# IAM role for Lambda execution
|
|
@@ -224,6 +280,13 @@ resource "aws_iam_role_policy_attachment" "lambda_xray_execution" {
|
|
|
224
280
|
role = aws_iam_role.lambda_execution_role.name
|
|
225
281
|
}
|
|
226
282
|
|
|
283
|
+
# Attach VPC access policy to Lambda role when deployed into a VPC
|
|
284
|
+
resource "aws_iam_role_policy_attachment" "lambda_vpc_access" {
|
|
285
|
+
count = var.enable_vpc ? 1 : 0
|
|
286
|
+
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
|
|
287
|
+
role = aws_iam_role.lambda_execution_role.name
|
|
288
|
+
}
|
|
289
|
+
|
|
227
290
|
# Additional IAM policies for Lambda (if provided)
|
|
228
291
|
resource "aws_iam_role_policy" "lambda_additional_policies" {
|
|
229
292
|
count = length(var.additional_iam_policy_statements) > 0 ? 1 : 0
|
|
@@ -794,6 +857,11 @@ output "lambda_execution_role_name" {
|
|
|
794
857
|
value = aws_iam_role.lambda_execution_role.name
|
|
795
858
|
}
|
|
796
859
|
|
|
860
|
+
output "security_group_id" {
|
|
861
|
+
description = "Security group ID of the API Lambda function, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true."
|
|
862
|
+
value = var.enable_vpc ? aws_security_group.api_lambda[0].id : null
|
|
863
|
+
}
|
|
864
|
+
|
|
797
865
|
# Integration Outputs
|
|
798
866
|
output "integration_id" {
|
|
799
867
|
description = "ID of the Lambda integration"
|