@aws/nx-plugin-mcp 1.0.0-rc.9 → 1.0.0-rc.90

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.
Files changed (200) hide show
  1. package/bin/aws-nx-mcp.js +14263 -13571
  2. package/docs/get_started/building-with-ai.mdx +116 -0
  3. package/docs/get_started/concepts.mdx +67 -0
  4. package/docs/get_started/existing-project.mdx +180 -0
  5. package/docs/get_started/graph-builder.mdx +39 -0
  6. package/docs/get_started/quick-start.mdx +277 -0
  7. package/docs/get_started/tutorials/contribute-generator.mdx +408 -0
  8. package/docs/get_started/tutorials/dungeon-game/1.mdx +1578 -0
  9. package/docs/get_started/tutorials/dungeon-game/2.mdx +245 -0
  10. package/docs/get_started/tutorials/dungeon-game/3.mdx +66 -0
  11. package/docs/get_started/tutorials/dungeon-game/4.mdx +164 -0
  12. package/docs/get_started/tutorials/dungeon-game/overview.mdx +145 -0
  13. package/docs/get_started/tutorials/dungeon-game/wrap-up.mdx +41 -0
  14. package/docs/get_started/upgrading.mdx +157 -0
  15. package/docs/guides/agentcore-gateway.mdx +490 -0
  16. package/docs/guides/agentcore-harness.mdx +312 -0
  17. package/docs/guides/astro-docs.mdx +8 -0
  18. package/docs/guides/connection/agentcore-gateway-agent.mdx +222 -0
  19. package/docs/guides/connection/agentcore-gateway-gateway.mdx +154 -0
  20. package/docs/guides/connection/agentcore-gateway-mcp.mdx +134 -0
  21. package/docs/guides/connection/py-agent-a2a.mdx +48 -16
  22. package/docs/guides/connection/py-agent-dynamodb.mdx +115 -0
  23. package/docs/guides/connection/py-agent-gateway.mdx +182 -0
  24. package/docs/guides/connection/py-agent-mcp.mdx +43 -14
  25. package/docs/guides/connection/py-agent-rdb.mdx +169 -0
  26. package/docs/guides/connection/py-fast-api-dynamodb.mdx +56 -0
  27. package/docs/guides/connection/py-fast-api-rdb.mdx +175 -0
  28. package/docs/guides/connection/py-mcp-server-dynamodb.mdx +115 -0
  29. package/docs/guides/connection/py-mcp-server-rdb.mdx +178 -0
  30. package/docs/guides/connection/react-agentcore-gateway.mdx +112 -0
  31. package/docs/guides/connection/react-agui.mdx +33 -14
  32. package/docs/guides/connection/react-fastapi.mdx +39 -3
  33. package/docs/guides/connection/react-py-agent.mdx +10 -16
  34. package/docs/guides/connection/react-smithy.mdx +4 -4
  35. package/docs/guides/connection/react-trpc.mdx +1 -1
  36. package/docs/guides/connection/react-ts-agent.mdx +9 -9
  37. package/docs/guides/connection/smithy-dynamodb.mdx +5 -5
  38. package/docs/guides/connection/smithy-rdb.mdx +9 -9
  39. package/docs/guides/connection/trpc-dynamodb.mdx +4 -4
  40. package/docs/guides/connection/trpc-rdb.mdx +5 -5
  41. package/docs/guides/connection/ts-agent-a2a.mdx +14 -11
  42. package/docs/guides/connection/ts-agent-dynamodb.mdx +35 -36
  43. package/docs/guides/connection/ts-agent-gateway.mdx +147 -0
  44. package/docs/guides/connection/ts-agent-mcp.mdx +12 -9
  45. package/docs/guides/connection/ts-agent-rdb.mdx +61 -25
  46. package/docs/guides/connection/ts-mcp-server-dynamodb.mdx +35 -36
  47. package/docs/guides/connection/ts-mcp-server-rdb.mdx +59 -18
  48. package/docs/guides/connection.mdx +122 -5
  49. package/docs/guides/docker-bundling.mdx +82 -14
  50. package/docs/guides/fastapi.mdx +253 -12
  51. package/docs/guides/local-development.mdx +87 -0
  52. package/docs/guides/nx-generator.mdx +4 -3
  53. package/docs/guides/nx-migration.mdx +165 -0
  54. package/docs/guides/py-agent.mdx +332 -55
  55. package/docs/guides/py-dynamodb.mdx +476 -0
  56. package/docs/guides/py-mcp-server.mdx +57 -2
  57. package/docs/guides/py-rdb.mdx +269 -0
  58. package/docs/guides/python-lambda-function.mdx +1 -1
  59. package/docs/guides/python-project.mdx +31 -0
  60. package/docs/guides/react-website-auth.mdx +104 -5
  61. package/docs/guides/react-website.mdx +409 -95
  62. package/docs/guides/runtime-config.mdx +17 -4
  63. package/docs/guides/security.mdx +75 -0
  64. package/docs/guides/smithy-project.mdx +167 -0
  65. package/docs/guides/terraform-project.mdx +119 -8
  66. package/docs/guides/trpc.mdx +55 -14
  67. package/docs/guides/ts-agent.mdx +207 -23
  68. package/docs/guides/ts-dcr-proxy.mdx +569 -0
  69. package/docs/guides/ts-dynamodb.mdx +66 -242
  70. package/docs/guides/ts-lambda-function.mdx +1 -1
  71. package/docs/guides/ts-mcp-server.mdx +111 -29
  72. package/docs/guides/ts-nx-plugin.mdx +4 -4
  73. package/docs/guides/ts-rdb.mdx +116 -466
  74. package/docs/guides/ts-smithy-api.mdx +260 -16
  75. package/docs/guides/typescript-infrastructure.mdx +79 -25
  76. package/docs/guides/typescript-project.mdx +157 -24
  77. package/docs/guides/workspace.mdx +31 -2
  78. package/docs/snippets/agent/architecture.mdx +1 -1
  79. package/docs/snippets/agent/bedrock-deployment.mdx +9 -5
  80. package/docs/snippets/agent/runtime-arn.mdx +23 -2
  81. package/docs/snippets/agent/securing-your-agent.mdx +39 -0
  82. package/docs/snippets/api/access-logging.mdx +38 -0
  83. package/docs/snippets/api/cors-configuration-cdk-note.mdx +1 -1
  84. package/docs/snippets/api/cors-configuration-terraform-note.mdx +1 -1
  85. package/docs/snippets/api/type-safe-api-integrations.mdx +218 -373
  86. package/docs/snippets/api/waf-configuration.mdx +3 -3
  87. package/docs/snippets/connection/a2a-infrastructure.mdx +1 -1
  88. package/docs/snippets/connection/dynamodb-local-development.mdx +2 -2
  89. package/docs/snippets/connection/lambda-dynamodb-access.mdx +2 -2
  90. package/docs/snippets/connection/py-dynamodb-local-development.mdx +7 -0
  91. package/docs/snippets/connection/py-lambda-rdb-ssl-requirements.mdx +7 -0
  92. package/docs/snippets/connection/rdb-api-infrastructure.mdx +42 -19
  93. package/docs/snippets/dynamodb/deploying-table.mdx +176 -0
  94. package/docs/snippets/dynamodb/encryption-options.mdx +168 -0
  95. package/docs/snippets/dynamodb/gsi-config.mdx +38 -0
  96. package/docs/snippets/dynamodb/infrastructure.mdx +33 -0
  97. package/docs/snippets/dynamodb/local-dev-start.mdx +13 -0
  98. package/docs/snippets/dynamodb/local-dev-windows.mdx +15 -0
  99. package/docs/snippets/experimental-generator.mdx +8 -0
  100. package/docs/snippets/lambda-function/deploying-your-function.mdx +3 -3
  101. package/docs/snippets/mcp/architecture.mdx +1 -1
  102. package/docs/snippets/mcp/bedrock-deployment.mdx +9 -5
  103. package/docs/snippets/mcp/config.mdx +3 -2
  104. package/docs/snippets/mcp/shared-constructs.mdx +4 -5
  105. package/docs/snippets/pdk-migration/example/01-migrate-api.mdx +7 -5
  106. package/docs/snippets/pdk-migration/example/02-migrate-website.mdx +29 -10
  107. package/docs/snippets/pdk-migration/example/03-migrate-infra.mdx +4 -4
  108. package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +5 -111
  109. package/docs/snippets/prerequisites.mdx +1 -4
  110. package/docs/snippets/rdb/admin-credentials.mdx +42 -0
  111. package/docs/snippets/rdb/architecture.mdx +39 -0
  112. package/docs/snippets/rdb/cluster-instances.mdx +31 -0
  113. package/docs/snippets/rdb/deletion-protection.mdx +64 -0
  114. package/docs/snippets/rdb/deploying.mdx +178 -0
  115. package/docs/snippets/rdb/encryption-key-rotation.mdx +30 -0
  116. package/docs/snippets/rdb/engine-version.mdx +63 -0
  117. package/docs/snippets/rdb/infrastructure.mdx +35 -0
  118. package/docs/snippets/rdb/logging-mysql.mdx +5 -0
  119. package/docs/snippets/rdb/logging-postgres.mdx +5 -0
  120. package/docs/snippets/rdb/performance-insights.mdx +36 -0
  121. package/docs/snippets/rdb/rds-proxy.mdx +50 -0
  122. package/docs/snippets/rdb/removal-policy.mdx +57 -0
  123. package/docs/snippets/rdb/serverless-capacity.mdx +32 -0
  124. package/docs/snippets/recommended-prerequisites.mdx +10 -0
  125. package/docs/snippets/required-prerequisites.mdx +1 -4
  126. package/docs/snippets/runtime-config-app-id-note.mdx +8 -0
  127. package/docs/snippets/shared-constructs.mdx +1 -1
  128. package/docs/snippets/trivy-image-scan.mdx +37 -0
  129. package/generators.json +170 -10
  130. package/package.json +1 -1
  131. package/src/agentcore-gateway/agent-connection/schema.json +31 -0
  132. package/src/agentcore-gateway/gateway-connection/schema.json +31 -0
  133. package/src/agentcore-gateway/mcp-connection/schema.json +31 -0
  134. package/src/agentcore-gateway/react-connection/schema.json +31 -0
  135. package/src/agentcore-gateway/schema.json +72 -0
  136. package/src/agentcore-harness/schema.json +53 -0
  137. package/src/connection/schema.json +5 -0
  138. package/src/infra/app/schema.json +5 -0
  139. package/src/init/schema.json +35 -0
  140. package/src/internal/test-matrix/schema.json +21 -0
  141. package/src/license/schema.json +5 -0
  142. package/src/open-api/json-metadata/schema.json +20 -0
  143. package/src/preset/schema.json +16 -5
  144. package/src/py/agent/a2a-connection/schema.json +5 -0
  145. package/src/py/agent/gateway-connection/schema.json +31 -0
  146. package/src/py/agent/mcp-connection/schema.json +5 -0
  147. package/src/py/agent/react-connection/schema.json +5 -0
  148. package/src/py/agent/schema.json +15 -1
  149. package/src/py/api/schema.json +5 -0
  150. package/src/py/dynamodb/agent-connection/schema.json +27 -0
  151. package/src/py/dynamodb/fast-api-connection/schema.json +23 -0
  152. package/src/py/dynamodb/mcp-server-connection/schema.json +27 -0
  153. package/src/py/dynamodb/schema.json +76 -0
  154. package/src/py/fast-api/react/schema.json +5 -0
  155. package/src/py/fast-api/schema.json +6 -0
  156. package/src/py/lambda-function/schema.json +6 -1
  157. package/src/py/mcp-server/schema.json +6 -0
  158. package/src/py/project/schema.json +6 -0
  159. package/src/py/rdb/agent-connection/schema.json +27 -0
  160. package/src/py/rdb/fast-api-connection/schema.json +23 -0
  161. package/src/py/rdb/mcp-server-connection/schema.json +27 -0
  162. package/src/py/rdb/schema.json +78 -0
  163. package/src/smithy/project/schema.json +28 -1
  164. package/src/smithy/react-connection/schema.json +5 -0
  165. package/src/smithy/ts/api/schema.json +6 -0
  166. package/src/terraform/project/schema.json +5 -0
  167. package/src/trpc/backend/schema.json +6 -0
  168. package/src/trpc/react/schema.json +5 -0
  169. package/src/ts/agent/a2a-connection/schema.json +5 -0
  170. package/src/ts/agent/gateway-connection/schema.json +31 -0
  171. package/src/ts/agent/mcp-connection/schema.json +5 -0
  172. package/src/ts/agent/react-connection/schema.json +5 -0
  173. package/src/ts/agent/schema.json +14 -0
  174. package/src/ts/api/schema.json +5 -0
  175. package/src/ts/astro-docs/schema.json +3 -3
  176. package/src/ts/dcr-proxy/schema.json +44 -0
  177. package/src/ts/docs/schema.json +3 -3
  178. package/src/ts/dynamodb/agent-connection/schema.json +5 -0
  179. package/src/ts/dynamodb/mcp-server-connection/schema.json +5 -0
  180. package/src/ts/dynamodb/schema.json +26 -2
  181. package/src/ts/dynamodb/smithy-connection/schema.json +5 -0
  182. package/src/ts/dynamodb/trpc-connection/schema.json +5 -0
  183. package/src/ts/lambda-function/schema.json +5 -0
  184. package/src/ts/lib/schema.json +5 -0
  185. package/src/ts/mcp-server/schema.json +6 -0
  186. package/src/ts/nx-generator/schema.json +5 -0
  187. package/src/ts/nx-migration/schema.json +63 -0
  188. package/src/ts/nx-plugin/schema.json +5 -0
  189. package/src/ts/rdb/agent-connection/schema.json +5 -0
  190. package/src/ts/rdb/mcp-server-connection/schema.json +5 -0
  191. package/src/ts/rdb/schema.json +7 -1
  192. package/src/ts/rdb/smithy-connection/schema.json +5 -0
  193. package/src/ts/rdb/trpc-connection/schema.json +5 -0
  194. package/src/ts/react-website/app/schema.json +12 -6
  195. package/src/ts/react-website/cognito-auth/schema.json +5 -0
  196. package/src/ts/react-website/runtime-config/schema.json +5 -0
  197. package/src/ts/website/app/schema.json +11 -6
  198. package/src/ts/website/auth/schema.json +5 -0
  199. /package/docs/snippets/connection/{lambda-rdb-ssl-requirements.mdx → ts-lambda-rdb-ssl-requirements.mdx} +0 -0
  200. /package/docs/snippets/connection/{mcp-server-rdb-ssl-requirements.mdx → ts-mcp-server-rdb-ssl-requirements.mdx} +0 -0
@@ -6,7 +6,7 @@ import Infrastructure from '@components/infrastructure.astro';
6
6
  For REST APIs, the generated construct associates an [AWS WAFv2](https://docs.aws.amazon.com/waf/latest/developerguide/waf-chapter.html) Web ACL with the API Gateway stage by default. The Web ACL uses the AWS managed default ruleset ([`AWSManagedRulesCommonRuleSet`](https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-baseline.html#aws-managed-rule-groups-baseline-crs) and [`AWSManagedRulesKnownBadInputsRuleSet`](https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-baseline.html#aws-managed-rule-groups-baseline-known-bad-inputs)), providing protection against common web exploits including the OWASP Top 10. WAF request logs are written to a CloudWatch Logs group.
7
7
 
8
8
  :::caution[SizeRestrictions_BODY deviation from defaults]
9
- The `SizeRestrictions_BODY` rule from `AWSManagedRulesCommonRuleSet` is overridden to `Count` rather than `Block`, since the rule's 8 KB limit is too restrictive for most APIs. Oversized requests will still be recorded as metrics so you can monitor them. See the [AWS WAF body size limits](https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-oversize-handling.html) guide for more details.
9
+ The `SizeRestrictions_BODY` rule from `AWSManagedRulesCommonRuleSet` is overridden to `Count` rather than `Block`, since the rule's 8 KB limit is too restrictive for most APIs. Oversized requests will still be recorded as metrics so you can monitor them. See the [AWS WAF body size limits](https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-oversize-handling.html) guide for more details. API Gateway natively enforces its [maximum payload size of 10 MB](https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html), returning a `413` for larger requests.
10
10
  :::
11
11
 
12
12
  You can edit the generated rest-api construct to add, remove, or adjust rules (for example, to add [rate-based rules](https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-type-rate-based.html) or additional managed rule groups).
@@ -15,7 +15,7 @@ You can edit the generated rest-api construct to add, remove, or adjust rules (f
15
15
  <Fragment slot="cdk">
16
16
  To opt out (for example, to attach your own Web ACL), set `enableWaf` to `false`:
17
17
 
18
- ```ts {4}
18
+ ```ts {3}
19
19
  const api = new MyApi(this, 'MyApi', {
20
20
  integrations: MyApi.defaultIntegrations(this).build(),
21
21
  enableWaf: false,
@@ -25,7 +25,7 @@ const api = new MyApi(this, 'MyApi', {
25
25
  <Fragment slot="terraform">
26
26
  To opt out (for example, to attach your own Web ACL), set `enable_waf` to `false`:
27
27
 
28
- ```hcl {4-5}
28
+ ```hcl {5}
29
29
  module "my_api" {
30
30
  source = "../../common/terraform/src/app/apis/my-api"
31
31
 
@@ -21,7 +21,7 @@ remoteAgent.grantInvokeAccess(myAgent);
21
21
  The remote agent's AgentCore runtime ARN is automatically registered in the `agentcore` namespace of <Link path="guides/runtime-config">Runtime Configuration</Link> by the generated CDK construct, so the host agent can discover it at runtime.
22
22
  </Fragment>
23
23
  <Fragment slot="terraform">
24
- ```hcl title="packages/infra/src/main.tf" {3-6, 11-12, 16-17}
24
+ ```hcl title="packages/infra/src/main.tf" {15-34}
25
25
  module "remote_agent" {
26
26
  source = "../../common/terraform/src/app/agents/remote-agent"
27
27
 
@@ -2,6 +2,6 @@
2
2
  title: DynamoDB Local Development
3
3
  ---
4
4
 
5
- The `connection` generator configures your project's `serve-local` target to depend on the DynamoDB project's `serve-local` target. DynamoDB Local will start automatically alongside your project when running `serve-local`.
5
+ The `connection` generator configures your project's `dev` target to depend on the DynamoDB project's `dev` target. DynamoDB Local will start automatically alongside your project when running `dev`.
6
6
 
7
- The `SERVE_LOCAL=true` environment variable is set automatically, so `getDynamoDBClient()` and `resolveTableName()` connect to the local DynamoDB Local instance instead of AWS.
7
+ The `LOCAL_DEV=true` environment variable is set automatically, so `getDynamoDBClient()` and `resolveTableName()` connect to the local DynamoDB Local instance instead of AWS.
@@ -11,7 +11,7 @@ To allow Lambda functions to access the DynamoDB table, grant the necessary perm
11
11
  Call `grantReadWriteData` on the table construct. This grants both the DynamoDB and KMS permissions required by the Lambda execution role:
12
12
 
13
13
  ```ts title="packages/infra/src/stacks/application-stack.ts"
14
- import { MyTable } from ':my-scope/common-constructs';
14
+ import { MyTable } from '@my-scope/common-constructs';
15
15
 
16
16
  const table = new MyTable(this, 'Table');
17
17
 
@@ -38,7 +38,7 @@ module "my_table" {
38
38
  }
39
39
 
40
40
  resource "aws_iam_role_policy" "dynamodb_access" {
41
- role = module.my_api.lambda_role_name
41
+ role = module.my_api.lambda_execution_role_name
42
42
 
43
43
  policy = jsonencode({
44
44
  Version = "2012-10-17"
@@ -0,0 +1,7 @@
1
+ ---
2
+ title: Python DynamoDB Local Development
3
+ ---
4
+
5
+ The `connection` generator configures your project's `dev` target to depend on the DynamoDB project's `dev` target. DynamoDB Local will start automatically alongside your project when running `dev`.
6
+
7
+ The `LOCAL_DEV=true` environment variable is set automatically, so `is_local()` returns `True` and your PynamoDB entities connect to the local DynamoDB instance instead of AWS.
@@ -0,0 +1,7 @@
1
+ ---
2
+ title: SSL Requirements when Connecting without RDS Proxy
3
+ ---
4
+
5
+ The Amazon Linux 2023 Lambda execution environment's built-in CA trust store includes the Amazon Root CAs used by RDS, so no additional configuration is needed.
6
+
7
+ When using RDS Proxy, you do not need to configure the RDS CA bundle in your Lambda function.
@@ -2,6 +2,7 @@
2
2
  title: RDB API Infrastructure
3
3
  ---
4
4
  import Infrastructure from '@components/infrastructure.astro';
5
+ import Link from '@components/link.astro';
5
6
 
6
7
  To allow your API to connect to the database at runtime, the API Lambda functions must be deployed into the same VPC as the database and granted network and IAM access.
7
8
 
@@ -11,7 +12,7 @@ To allow your API to connect to the database at runtime, the API Lambda function
11
12
  In your application stack, deploy the API into the same VPC as the database, then call `allowDefaultPortFrom` and `grantConnect` to open the network path and grant IAM `rds-db:connect` permission to each Lambda handler:
12
13
 
13
14
  ```ts title="packages/infra/src/stacks/application-stack.ts"
14
- import { MyDatabase } from ':my-scope/common-constructs';
15
+ import { MyDatabase } from '@my-scope/common-constructs';
15
16
 
16
17
  const db = new MyDatabase(this, 'Db', { vpc, ... });
17
18
 
@@ -39,34 +40,56 @@ This example grants every handler in your API access, but if only some handlers
39
40
  </Fragment>
40
41
  <Fragment slot="terraform">
41
42
 
42
- Pass the database module outputs into your API module so it can reach the database and read its runtime configuration:
43
+ Deploy the API into the same VPC as the database, grant it `rds-db:connect` via `additional_iam_policy_statements`, and open the network path with a pair of security group rules. The `aws_vpc.main` and `aws_subnet` resources are defined in the database deployment guide:
43
44
 
44
45
  ```hcl title="packages/infra/src/main.tf"
45
46
  module "my_database" {
46
47
  source = "../../common/terraform/src/app/dbs/my-database"
47
- vpc_id = module.vpc.vpc_id
48
- database_subnet_ids = module.vpc.private_isolated_subnet_ids
49
- lambda_subnet_ids = module.vpc.private_subnet_ids
48
+ vpc_id = aws_vpc.main.id
49
+ database_subnet_ids = aws_subnet.database[*].id
50
+ lambda_subnet_ids = aws_subnet.private[*].id
50
51
  }
51
52
 
52
53
  module "api" {
53
- source = "..."
54
- vpc_id = module.vpc.vpc_id
55
- private_subnet_ids = module.vpc.private_subnet_ids
56
-
57
- appconfig_application_id = module.my_database.appconfig_application_id
58
- database_cluster_resource_id = module.my_database.cluster_resource_id
59
- database_runtime_user = module.my_database.database_runtime_user
60
- database_security_group_id = module.my_database.security_group_id
61
- database_port = module.my_database.cluster_port
62
-
63
- environment_variables = {
64
- RUNTIME_CONFIG_APP_ID = module.my_database.appconfig_application_id
65
- }
54
+ source = "../../common/terraform/src/app/apis/my-api"
55
+ enable_vpc = true
56
+ vpc_id = aws_vpc.main.id
57
+ subnet_ids = aws_subnet.private[*].id
58
+
59
+ appconfig_application_id = module.runtime_config_appconfig.application_id
60
+ appconfig_application_arn = module.runtime_config_appconfig.application_arn
61
+
62
+ additional_iam_policy_statements = [
63
+ {
64
+ Effect = "Allow"
65
+ Action = ["rds-db:connect"]
66
+ Resource = [
67
+ "arn:aws:rds-db:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:dbuser:${module.my_database.connect_resource_id}/${module.my_database.database_runtime_user}"
68
+ ]
69
+ }
70
+ ]
71
+ }
72
+
73
+ resource "aws_vpc_security_group_ingress_rule" "api_to_database" {
74
+ description = "Allow the API Lambda functions to connect to the database"
75
+ security_group_id = module.my_database.security_group_id
76
+ referenced_security_group_id = module.api.security_group_id
77
+ from_port = module.my_database.cluster_port
78
+ to_port = module.my_database.cluster_port
79
+ ip_protocol = "tcp"
80
+ }
81
+
82
+ resource "aws_vpc_security_group_egress_rule" "api_to_database" {
83
+ description = "Allow outbound traffic from the API Lambda functions to the database"
84
+ security_group_id = module.api.security_group_id
85
+ referenced_security_group_id = module.my_database.security_group_id
86
+ from_port = module.my_database.cluster_port
87
+ to_port = module.my_database.cluster_port
88
+ ip_protocol = "tcp"
66
89
  }
67
90
  ```
68
91
 
69
- Deploy the API Lambda functions into **private subnets with egress**, not private isolated subnets. Ensure the API Lambda role has `rds-db:connect` permission and that its security group can reach the database security group on the database port.
92
+ Deploy the API Lambda functions into **private subnets with egress**, not private isolated subnets. `appconfig_application_id`/`appconfig_application_arn` come from the shared <Link path="guides/runtime-config">runtime configuration</Link> AppConfig application declared once in your root module, not from the database module — passing them sets `RUNTIME_CONFIG_APP_ID` on the Lambda functions and grants them read access to the application. That application exposes the `database` namespace by default, so the database module's runtime configuration entry is deployed without further configuration.
70
93
 
71
94
  </Fragment>
72
95
  </Infrastructure>
@@ -0,0 +1,176 @@
1
+ ---
2
+ title: Deploying your DynamoDB Table
3
+ ---
4
+ import Infrastructure from '@components/infrastructure.astro';
5
+ import Snippet from '@components/snippet.astro';
6
+
7
+ The DynamoDB generator creates CDK or Terraform infrastructure based on your selected `iac`.
8
+
9
+ <Infrastructure>
10
+ <Fragment slot="cdk">
11
+ The CDK construct is created in `common/constructs`. Example usage:
12
+
13
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
14
+ import { MyTable } from '@my-scope/common-constructs';
15
+
16
+ export class ApplicationStack extends Stack {
17
+ constructor(scope: Construct, id: string, props?: StackProps) {
18
+ super(scope, id, props);
19
+
20
+ const table = new MyTable(this, 'Table');
21
+ }
22
+ }
23
+ ```
24
+
25
+ This provisions a DynamoDB table with:
26
+ - `pk` (partition key) and `sk` (sort key), both `String` type
27
+ - Global Secondary Indexes as defined in `config.json`
28
+ - On-demand (`PAY_PER_REQUEST`) billing
29
+ - Customer-managed KMS encryption with automatic key rotation
30
+ - Point-in-time recovery enabled
31
+ - Deletion protection enabled
32
+ - Table name registered in Runtime Config under the `dynamodb` namespace in AWS AppConfig
33
+ </Fragment>
34
+ <Fragment slot="terraform">
35
+ The Terraform module is created in `common/terraform`. Example usage:
36
+
37
+ ```hcl title="packages/infra/src/main.tf"
38
+ module "my_table" {
39
+ source = "../../common/terraform/src/app/dynamodb/my-table"
40
+ }
41
+ ```
42
+
43
+ This provisions a DynamoDB table with:
44
+ - `pk` (partition key) and `sk` (sort key), both `String` type
45
+ - Global Secondary Indexes as defined in `config.json`
46
+ - On-demand (`PAY_PER_REQUEST`) billing
47
+ - Customer-managed KMS encryption with automatic key rotation
48
+ - Point-in-time recovery enabled
49
+ - Deletion protection enabled, plus a `prevent_destroy` lifecycle guard
50
+ - Table name registered in Runtime Config under the `dynamodb` namespace in AWS AppConfig
51
+
52
+ The `core/runtime-config/appconfig` module exposes the `dynamodb` namespace by default, so the table name is deployed without further configuration. If you pass `namespaces` to that module explicitly, keep `dynamodb` in the list — otherwise no configuration profile is created for it and the generated table client cannot resolve the table name.
53
+ </Fragment>
54
+ </Infrastructure>
55
+
56
+ ### Deletion Protection
57
+
58
+ The table is protected by two independent guards, so that turning off either one alone cannot delete your data:
59
+
60
+ <Infrastructure>
61
+ <Fragment slot="cdk">
62
+ - `deletionProtection`, enforced by DynamoDB.
63
+ - `RemovalPolicy.RETAIN`, enforced by CloudFormation, which leaves the table in place when it is removed from the stack.
64
+ </Fragment>
65
+ <Fragment slot="terraform">
66
+ - `deletion_protection_enabled`, enforced by DynamoDB.
67
+ - `lifecycle { prevent_destroy = true }` on the table in `common/terraform/src/core/dynamodb/dynamodb.tf`, enforced by Terraform, which fails any plan that would destroy the table.
68
+ </Fragment>
69
+ </Infrastructure>
70
+
71
+ #### Deleting the Table
72
+
73
+ Disable protection for environments where table deletion is expected, such as short-lived development or preview stacks.
74
+
75
+ <Infrastructure>
76
+ <Fragment slot="cdk">
77
+
78
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
79
+ import { RemovalPolicy } from 'aws-cdk-lib';
80
+ import { MyTable } from '@my-scope/common-constructs';
81
+
82
+ const table = new MyTable(this, 'Table', {
83
+ deletionProtection: false,
84
+ removalPolicy: RemovalPolicy.DESTROY,
85
+ });
86
+ ```
87
+ </Fragment>
88
+ <Fragment slot="terraform">
89
+
90
+ ```hcl title="packages/infra/src/main.tf"
91
+ module "my_table" {
92
+ source = "../../common/terraform/src/app/dynamodb/my-table"
93
+ deletion_protection_enabled = false
94
+ }
95
+ ```
96
+
97
+ `prevent_destroy` must be a literal — Terraform does not allow it to reference a variable — so it cannot be turned off from `main.tf`. Also remove the `lifecycle` block from the table in `common/terraform/src/core/dynamodb/dynamodb.tf`:
98
+
99
+ ```hcl title="packages/common/terraform/src/core/dynamodb/dynamodb.tf" del={4-6}
100
+ resource "aws_dynamodb_table" "table" {
101
+ # ...
102
+
103
+ lifecycle {
104
+ prevent_destroy = true
105
+ }
106
+ }
107
+ ```
108
+
109
+ :::caution
110
+ This module is shared by every table in your workspace, so removing the block removes that guard for all of them.
111
+ :::
112
+ </Fragment>
113
+ </Infrastructure>
114
+
115
+ ### Billing Mode
116
+
117
+ The table defaults to on-demand (`PAY_PER_REQUEST`) billing. Switch to provisioned capacity for predictable, high-throughput workloads.
118
+
119
+ <Infrastructure>
120
+ <Fragment slot="cdk">
121
+
122
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
123
+ import { BillingMode } from 'aws-cdk-lib/aws-dynamodb';
124
+ import { MyTable } from '@my-scope/common-constructs';
125
+
126
+ const table = new MyTable(this, 'Table', {
127
+ billingMode: BillingMode.PROVISIONED,
128
+ readCapacity: 5,
129
+ writeCapacity: 5,
130
+ });
131
+ ```
132
+ </Fragment>
133
+ <Fragment slot="terraform">
134
+
135
+ ```hcl title="packages/infra/src/main.tf"
136
+ module "my_table" {
137
+ source = "../../common/terraform/src/app/dynamodb/my-table"
138
+ billing_mode = "PROVISIONED"
139
+ }
140
+ ```
141
+ </Fragment>
142
+ </Infrastructure>
143
+
144
+ ### Point-in-time Recovery
145
+
146
+ [Point-in-time recovery](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Point-in-time-recovery.html) is enabled by default, allowing you to restore the table to any point in the last 35 days.
147
+
148
+ #### Disable Point-in-time Recovery
149
+
150
+ <Infrastructure>
151
+ <Fragment slot="cdk">
152
+
153
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
154
+ import { MyTable } from '@my-scope/common-constructs';
155
+
156
+ const table = new MyTable(this, 'Table', {
157
+ pointInTimeRecoverySpecification: { pointInTimeRecoveryEnabled: false },
158
+ });
159
+ ```
160
+ </Fragment>
161
+ <Fragment slot="terraform">
162
+
163
+ ```hcl title="packages/infra/src/main.tf"
164
+ module "my_table" {
165
+ source = "../../common/terraform/src/app/dynamodb/my-table"
166
+ point_in_time_recovery_enabled = false
167
+ }
168
+ ```
169
+ </Fragment>
170
+ </Infrastructure>
171
+
172
+ ### Encryption
173
+
174
+ The table is encrypted with a customer-managed KMS key by default, created automatically for you. Switch to an AWS managed key, the AWS owned key, or bring your own KMS key, if you manage encryption differently.
175
+
176
+ <Snippet name="dynamodb/encryption-options" parentHeading="Encryption" />
@@ -0,0 +1,168 @@
1
+ ---
2
+ title: Encryption Options
3
+ ---
4
+ import Infrastructure from '@components/infrastructure.astro';
5
+ import OptionFilter from '@components/option-filter.astro';
6
+
7
+ #### Use an AWS Managed Key
8
+
9
+ Uses the shared `aws/dynamodb` KMS key that AWS manages on your behalf. It's visible in your account's KMS console and billed per request, but there's no key for you to create, rotate or delete.
10
+
11
+ <Infrastructure>
12
+ <Fragment slot="cdk">
13
+
14
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
15
+ import { TableEncryption } from 'aws-cdk-lib/aws-dynamodb';
16
+ import { MyTable } from '@my-scope/common-constructs';
17
+
18
+ const table = new MyTable(this, 'Table', {
19
+ encryption: TableEncryption.AWS_MANAGED,
20
+ });
21
+ ```
22
+
23
+ :::tip[Checkov]
24
+ Choosing `AWS_MANAGED` means the table is no longer encrypted with a customer-managed key, which fails Checkov's `CKV_AWS_119`. Suppress it on the table:
25
+
26
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
27
+ import { suppressRules } from '@my-scope/common-constructs';
28
+
29
+ suppressRules(table.table, ['CKV_AWS_119'], 'Using an AWS managed key rather than a customer-managed CMK');
30
+ ```
31
+ :::
32
+ </Fragment>
33
+ <Fragment slot="terraform">
34
+
35
+ ```hcl title="packages/infra/src/main.tf"
36
+ module "my_table" {
37
+ source = "../../common/terraform/src/app/dynamodb/my-table"
38
+ encryption = "AWS_MANAGED"
39
+ }
40
+ ```
41
+ </Fragment>
42
+ </Infrastructure>
43
+
44
+ #### Use the AWS Owned Key
45
+
46
+ Uses a key fully owned and managed by AWS — free, with no key visible in your account at all. The simplest option when you don't need a customer- or account-visible key for compliance reasons.
47
+
48
+ <Infrastructure>
49
+ <Fragment slot="cdk">
50
+
51
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
52
+ import { TableEncryption } from 'aws-cdk-lib/aws-dynamodb';
53
+ import { MyTable } from '@my-scope/common-constructs';
54
+
55
+ const table = new MyTable(this, 'Table', {
56
+ encryption: TableEncryption.DEFAULT,
57
+ });
58
+ ```
59
+
60
+ :::tip[Checkov]
61
+ Choosing `DEFAULT` means the table is no longer encrypted with a customer-managed key, which fails Checkov's `CKV_AWS_119`. Suppress it on the table:
62
+
63
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
64
+ import { suppressRules } from '@my-scope/common-constructs';
65
+
66
+ suppressRules(table.table, ['CKV_AWS_119'], 'Using the AWS owned key rather than a customer-managed CMK');
67
+ ```
68
+ :::
69
+ </Fragment>
70
+ <Fragment slot="terraform">
71
+
72
+ ```hcl title="packages/infra/src/main.tf"
73
+ module "my_table" {
74
+ source = "../../common/terraform/src/app/dynamodb/my-table"
75
+ encryption = "DEFAULT"
76
+ }
77
+ ```
78
+ </Fragment>
79
+ </Infrastructure>
80
+
81
+ <OptionFilter when={{ iac: 'terraform' }} description="Switching an already-deployed table away from CUSTOMER_MANAGED">
82
+ #### Switching away from CUSTOMER_MANAGED
83
+
84
+ On an **already-deployed** table, changing `encryption` away from `CUSTOMER_MANAGED` (to either `AWS_MANAGED` or `DEFAULT`) in a single `terraform apply` fails: Terraform destroys the customer-managed key before updating the table, and DynamoDB then rejects the update because the key is already pending deletion.
85
+
86
+ Work around it by updating the table's encryption directly via the AWS CLI first, then letting Terraform catch up and clean up the orphaned key:
87
+
88
+ ```bash
89
+ # For AWS_MANAGED:
90
+ aws dynamodb update-table --table-name <table-name> \
91
+ --sse-specification Enabled=true,SSEType=KMS,KMSMasterKeyId=alias/aws/dynamodb
92
+
93
+ # For DEFAULT:
94
+ aws dynamodb update-table --table-name <table-name> --sse-specification Enabled=false
95
+
96
+ # Then wait for this to report ENABLED (or for SSEDescription to disappear, for DEFAULT):
97
+ aws dynamodb describe-table --table-name <table-name> --query Table.SSEDescription.Status
98
+ ```
99
+
100
+ Then update `encryption` in your Terraform config and run `terraform apply` as normal — Terraform now only needs to destroy the already-unused key, with nothing left depending on it.
101
+ </OptionFilter>
102
+
103
+ #### Use Your Own KMS Key
104
+
105
+ Provide an existing customer-managed key instead of having one created for you. The key must already grant the DynamoDB service the permissions it needs in its own key policy.
106
+
107
+ <Infrastructure>
108
+ <Fragment slot="cdk">
109
+
110
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
111
+ import { Key } from 'aws-cdk-lib/aws-kms';
112
+ import { MyTable } from '@my-scope/common-constructs';
113
+
114
+ const key = Key.fromKeyArn(this, 'Key', 'arn:aws:kms:us-east-1:111111111111:key/my-key-id');
115
+
116
+ const table = new MyTable(this, 'Table', {
117
+ encryptionKey: key,
118
+ });
119
+ ```
120
+ </Fragment>
121
+ <Fragment slot="terraform">
122
+
123
+ ```hcl title="packages/infra/src/main.tf"
124
+ module "my_table" {
125
+ source = "../../common/terraform/src/app/dynamodb/my-table"
126
+ kms_key_arn = "arn:aws:kms:us-east-1:111111111111:key/my-key-id"
127
+ }
128
+ ```
129
+ </Fragment>
130
+ </Infrastructure>
131
+
132
+ #### Encryption Key Rotation
133
+
134
+ When the table creates its own customer-managed KMS key (the default, and only when you haven't provided your own key), that key has automatic key rotation enabled by default. Disable it if your security policy manages rotation externally.
135
+
136
+ ##### Disable Encryption Key Rotation
137
+
138
+ <Infrastructure>
139
+ <Fragment slot="cdk">
140
+
141
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
142
+ import { MyTable } from '@my-scope/common-constructs';
143
+
144
+ const table = new MyTable(this, 'Table', {
145
+ enableKeyRotation: false,
146
+ });
147
+ ```
148
+
149
+ :::tip[Checkov]
150
+ Disabling key rotation, or bringing your own key that doesn't rotate, fails Checkov's `CKV_AWS_7`. Suppress it on the key:
151
+
152
+ ```ts title="packages/infra/src/stacks/application-stack.ts"
153
+ import { suppressRules } from '@my-scope/common-constructs';
154
+
155
+ suppressRules(table.table.encryptionKey!, ['CKV_AWS_7'], 'Key rotation is managed externally');
156
+ ```
157
+ :::
158
+ </Fragment>
159
+ <Fragment slot="terraform">
160
+
161
+ ```hcl title="packages/infra/src/main.tf"
162
+ module "my_table" {
163
+ source = "../../common/terraform/src/app/dynamodb/my-table"
164
+ enable_key_rotation = false
165
+ }
166
+ ```
167
+ </Fragment>
168
+ </Infrastructure>
@@ -0,0 +1,38 @@
1
+ ---
2
+ title: GSI Configuration
3
+ ---
4
+
5
+ ```json title="config.json"
6
+ {
7
+ ...
8
+ "tableConfig": {
9
+ "globalSecondaryIndexes": [
10
+ {
11
+ "indexName": "gsi1pk-gsi1sk-index",
12
+ "partitionKey": "gsi1pk",
13
+ "sortKey": "gsi1sk"
14
+ },
15
+ {
16
+ "indexName": "gsi2pk-gsi2sk-index",
17
+ "partitionKey": "gsi2pk",
18
+ "sortKey": "gsi2sk"
19
+ }
20
+ ]
21
+ }
22
+ }
23
+ ```
24
+
25
+ The `sortKey` field is optional for hash-key-only GSIs.
26
+
27
+ This config file is the single source of truth read by all consumers:
28
+ - **Local development** — `dev` reads `config.json` and creates or updates the local table to match the GSI list
29
+ - **CDK** — the construct reads `config.json` at synth time, so GSI changes are reflected on the next `cdk deploy`
30
+ - **Terraform** — the module reads `config.json` at plan/apply time
31
+
32
+ ### One GSI per Deployment
33
+
34
+ :::caution
35
+ DynamoDB [does not allow more than one GSI to be created or deleted in a single table update](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.OnlineOps.html).
36
+
37
+ Each deployment can add or remove **at most one GSI**. If you need to add or remove multiple GSIs, do so one at a time — update `config.json` and relevant entity classes, deploy the stack, then repeat for the next change.
38
+ :::
@@ -0,0 +1,33 @@
1
+ ---
2
+ title: DynamoDB Infrastructure
3
+ ---
4
+ import { FileTree } from '@astrojs/starlight/components';
5
+ import Infrastructure from '@components/infrastructure.astro';
6
+ import Snippet from '@components/snippet.astro';
7
+
8
+ <Snippet name="shared-constructs" />
9
+
10
+ <Infrastructure>
11
+ <Fragment slot="cdk">
12
+ <FileTree>
13
+ - packages/common/constructs/src
14
+ - app
15
+ - dynamodb
16
+ - \<name>.ts Infrastructure specific to your table
17
+ - core
18
+ - dynamodb.ts Generic DynamoDB table construct
19
+ </FileTree>
20
+ </Fragment>
21
+ <Fragment slot="terraform">
22
+ <FileTree>
23
+ - packages/common/terraform/src
24
+ - app
25
+ - dynamodb
26
+ - \<name>
27
+ - \<name>.tf Module specific to your table
28
+ - core
29
+ - dynamodb
30
+ - dynamodb.tf Generic DynamoDB module
31
+ </FileTree>
32
+ </Fragment>
33
+ </Infrastructure>
@@ -0,0 +1,13 @@
1
+ ---
2
+ title: Starting Local DynamoDB
3
+ ---
4
+ import NxCommands from '@components/nx-commands.astro';
5
+
6
+ The generator configures a `dev` target that starts a [DynamoDB Local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html) instance and creates the table. Use the project's `dev` target:
7
+
8
+ <NxCommands commands={['dev <project-name>']} />
9
+
10
+ This automatically:
11
+ 1. Pulls the DynamoDB Local image (`pull-image` target)
12
+ 2. Starts a container
13
+ 3. Creates a local table with the indexes defined in `config.json`
@@ -0,0 +1,15 @@
1
+ ---
2
+ title: Local Development Windows Caution
3
+ ---
4
+
5
+ Stopping `dev` (e.g. with `Ctrl+C`) automatically removes the DynamoDB Local container, but preserves the named volume so your data persists across restarts.
6
+
7
+ :::caution[Windows]
8
+ Due to limitations with signal handling on Windows, the container is not automatically removed when `dev` is stopped. You will need to remove it manually:
9
+
10
+ ```bash
11
+ <engine> rm -f <scope>-dynamodb
12
+ ```
13
+
14
+ Replace `<engine>` with your container engine (`docker` or `finch`) and `<scope>` with your Nx workspace scope (e.g. `proj`).
15
+ :::
@@ -0,0 +1,8 @@
1
+ ---
2
+ title: Experimental Generator
3
+ ---
4
+ import Link from '@components/link.astro';
5
+
6
+ :::caution[Experimental]
7
+ This generator is experimental. Its behaviour and generated output may change in a future release without a <Link path="get_started/upgrading">migration</Link> being published to apply the change to an existing workspace, so you may need to reconcile those changes yourself when you upgrade.
8
+ :::
@@ -3,14 +3,14 @@ title: Deploying your Function
3
3
  ---
4
4
  import Infrastructure from '@components/infrastructure.astro';
5
5
 
6
- This generator creates CDK or Terraform infrastructure as code based on your selected `iacProvider`. You can use this to deploy your function.
6
+ This generator creates CDK or Terraform infrastructure as code based on your selected `iac`. You can use this to deploy your function.
7
7
 
8
8
  <Infrastructure>
9
9
  <Fragment slot="cdk">
10
10
  This generator creates a CDK construct for deploying your function in the `common/constructs` folder. You can use this in a CDK application:
11
11
 
12
12
  ```typescript {1, 6}
13
- import { MyProjectMyFunction } from ':my-scope/common-constructs';
13
+ import { MyProjectMyFunction } from '@my-scope/common-constructs';
14
14
 
15
15
  export class ExampleStack extends Stack {
16
16
  constructor(scope: Construct, id: string) {
@@ -38,7 +38,7 @@ The example below demonstrates the CDK code for invoking your lambda function on
38
38
  ```typescript
39
39
  import { Rule, Schedule } from 'aws-cdk-lib/aws-events';
40
40
  import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets';
41
- import { MyProjectMyFunction } from ':my-scope/common-constructs';
41
+ import { MyProjectMyFunction } from '@my-scope/common-constructs';
42
42
 
43
43
  export class ExampleStack extends Stack {
44
44
  constructor(scope: Construct, id: string) {