@aws/nx-plugin-mcp 1.0.0-rc.9 → 1.0.0-rc.91
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/bin/aws-nx-mcp.js +13439 -11631
- package/docs/get_started/building-with-ai.mdx +116 -0
- package/docs/get_started/concepts.mdx +67 -0
- package/docs/get_started/existing-project.mdx +180 -0
- package/docs/get_started/graph-builder.mdx +39 -0
- package/docs/get_started/quick-start.mdx +277 -0
- package/docs/get_started/tutorials/contribute-generator.mdx +408 -0
- package/docs/get_started/tutorials/dungeon-game/1.mdx +1578 -0
- package/docs/get_started/tutorials/dungeon-game/2.mdx +245 -0
- package/docs/get_started/tutorials/dungeon-game/3.mdx +66 -0
- package/docs/get_started/tutorials/dungeon-game/4.mdx +164 -0
- package/docs/get_started/tutorials/dungeon-game/overview.mdx +145 -0
- package/docs/get_started/tutorials/dungeon-game/wrap-up.mdx +41 -0
- package/docs/get_started/upgrading.mdx +157 -0
- package/docs/guides/agentcore-gateway.mdx +490 -0
- package/docs/guides/agentcore-harness.mdx +312 -0
- package/docs/guides/astro-docs.mdx +8 -0
- package/docs/guides/connection/agentcore-gateway-agent.mdx +222 -0
- package/docs/guides/connection/agentcore-gateway-gateway.mdx +154 -0
- package/docs/guides/connection/agentcore-gateway-mcp.mdx +134 -0
- package/docs/guides/connection/py-agent-a2a.mdx +48 -16
- package/docs/guides/connection/py-agent-dynamodb.mdx +115 -0
- package/docs/guides/connection/py-agent-gateway.mdx +182 -0
- package/docs/guides/connection/py-agent-mcp.mdx +43 -14
- package/docs/guides/connection/py-agent-rdb.mdx +169 -0
- package/docs/guides/connection/py-fast-api-dynamodb.mdx +56 -0
- package/docs/guides/connection/py-fast-api-rdb.mdx +175 -0
- package/docs/guides/connection/py-mcp-server-dynamodb.mdx +115 -0
- package/docs/guides/connection/py-mcp-server-rdb.mdx +178 -0
- package/docs/guides/connection/react-agentcore-gateway.mdx +112 -0
- package/docs/guides/connection/react-agui.mdx +33 -14
- package/docs/guides/connection/react-fastapi.mdx +39 -3
- package/docs/guides/connection/react-py-agent.mdx +10 -16
- package/docs/guides/connection/react-smithy.mdx +4 -4
- package/docs/guides/connection/react-trpc.mdx +1 -1
- package/docs/guides/connection/react-ts-agent.mdx +9 -9
- package/docs/guides/connection/smithy-dynamodb.mdx +5 -5
- package/docs/guides/connection/smithy-rdb.mdx +9 -9
- package/docs/guides/connection/trpc-dynamodb.mdx +4 -4
- package/docs/guides/connection/trpc-rdb.mdx +5 -5
- package/docs/guides/connection/ts-agent-a2a.mdx +14 -11
- package/docs/guides/connection/ts-agent-dynamodb.mdx +35 -36
- package/docs/guides/connection/ts-agent-gateway.mdx +147 -0
- package/docs/guides/connection/ts-agent-mcp.mdx +12 -9
- package/docs/guides/connection/ts-agent-rdb.mdx +61 -25
- package/docs/guides/connection/ts-mcp-server-dynamodb.mdx +35 -36
- package/docs/guides/connection/ts-mcp-server-rdb.mdx +59 -18
- package/docs/guides/connection.mdx +122 -5
- package/docs/guides/docker-bundling.mdx +82 -14
- package/docs/guides/fastapi.mdx +253 -12
- package/docs/guides/local-development.mdx +87 -0
- package/docs/guides/nx-generator.mdx +4 -3
- package/docs/guides/nx-migration.mdx +165 -0
- package/docs/guides/py-agent.mdx +332 -55
- package/docs/guides/py-dynamodb.mdx +476 -0
- package/docs/guides/py-mcp-server.mdx +57 -2
- package/docs/guides/py-rdb.mdx +269 -0
- package/docs/guides/python-lambda-function.mdx +1 -1
- package/docs/guides/python-project.mdx +31 -0
- package/docs/guides/react-website-auth.mdx +104 -5
- package/docs/guides/react-website.mdx +409 -95
- package/docs/guides/runtime-config.mdx +17 -4
- package/docs/guides/security.mdx +75 -0
- package/docs/guides/smithy-project.mdx +167 -0
- package/docs/guides/terraform-project.mdx +119 -8
- package/docs/guides/trpc.mdx +55 -14
- package/docs/guides/ts-agent.mdx +207 -23
- package/docs/guides/ts-dcr-proxy.mdx +569 -0
- package/docs/guides/ts-dynamodb.mdx +66 -242
- package/docs/guides/ts-lambda-function.mdx +1 -1
- package/docs/guides/ts-mcp-server.mdx +111 -29
- package/docs/guides/ts-nx-plugin.mdx +4 -4
- package/docs/guides/ts-rdb.mdx +116 -466
- package/docs/guides/ts-smithy-api.mdx +260 -16
- package/docs/guides/typescript-infrastructure.mdx +79 -25
- package/docs/guides/typescript-project.mdx +157 -24
- package/docs/guides/workspace.mdx +31 -2
- package/docs/snippets/agent/architecture.mdx +1 -1
- package/docs/snippets/agent/bedrock-deployment.mdx +9 -5
- package/docs/snippets/agent/runtime-arn.mdx +23 -2
- package/docs/snippets/agent/securing-your-agent.mdx +39 -0
- package/docs/snippets/api/access-logging.mdx +38 -0
- package/docs/snippets/api/cors-configuration-cdk-note.mdx +1 -1
- package/docs/snippets/api/cors-configuration-terraform-note.mdx +1 -1
- package/docs/snippets/api/type-safe-api-integrations.mdx +218 -373
- package/docs/snippets/api/waf-configuration.mdx +3 -3
- package/docs/snippets/connection/a2a-infrastructure.mdx +1 -1
- package/docs/snippets/connection/dynamodb-local-development.mdx +2 -2
- package/docs/snippets/connection/lambda-dynamodb-access.mdx +2 -2
- package/docs/snippets/connection/py-dynamodb-local-development.mdx +7 -0
- package/docs/snippets/connection/py-lambda-rdb-ssl-requirements.mdx +7 -0
- package/docs/snippets/connection/rdb-api-infrastructure.mdx +42 -19
- package/docs/snippets/dynamodb/deploying-table.mdx +176 -0
- package/docs/snippets/dynamodb/encryption-options.mdx +168 -0
- package/docs/snippets/dynamodb/gsi-config.mdx +38 -0
- package/docs/snippets/dynamodb/infrastructure.mdx +33 -0
- package/docs/snippets/dynamodb/local-dev-start.mdx +13 -0
- package/docs/snippets/dynamodb/local-dev-windows.mdx +15 -0
- package/docs/snippets/experimental-generator.mdx +8 -0
- package/docs/snippets/lambda-function/deploying-your-function.mdx +3 -3
- package/docs/snippets/mcp/architecture.mdx +1 -1
- package/docs/snippets/mcp/bedrock-deployment.mdx +9 -5
- package/docs/snippets/mcp/config.mdx +3 -2
- package/docs/snippets/mcp/shared-constructs.mdx +4 -5
- package/docs/snippets/pdk-migration/example/01-migrate-api.mdx +7 -5
- package/docs/snippets/pdk-migration/example/02-migrate-website.mdx +29 -10
- package/docs/snippets/pdk-migration/example/03-migrate-infra.mdx +4 -4
- package/docs/snippets/pdk-migration/faq/type-safe-api.mdx +5 -111
- package/docs/snippets/prerequisites.mdx +1 -4
- package/docs/snippets/rdb/admin-credentials.mdx +42 -0
- package/docs/snippets/rdb/architecture.mdx +39 -0
- package/docs/snippets/rdb/cluster-instances.mdx +31 -0
- package/docs/snippets/rdb/deletion-protection.mdx +64 -0
- package/docs/snippets/rdb/deploying.mdx +178 -0
- package/docs/snippets/rdb/encryption-key-rotation.mdx +30 -0
- package/docs/snippets/rdb/engine-version.mdx +63 -0
- package/docs/snippets/rdb/infrastructure.mdx +35 -0
- package/docs/snippets/rdb/logging-mysql.mdx +5 -0
- package/docs/snippets/rdb/logging-postgres.mdx +5 -0
- package/docs/snippets/rdb/performance-insights.mdx +36 -0
- package/docs/snippets/rdb/rds-proxy.mdx +50 -0
- package/docs/snippets/rdb/removal-policy.mdx +57 -0
- package/docs/snippets/rdb/serverless-capacity.mdx +32 -0
- package/docs/snippets/recommended-prerequisites.mdx +10 -0
- package/docs/snippets/required-prerequisites.mdx +1 -4
- package/docs/snippets/runtime-config-app-id-note.mdx +8 -0
- package/docs/snippets/shared-constructs.mdx +1 -1
- package/docs/snippets/trivy-image-scan.mdx +37 -0
- package/generators.json +170 -10
- package/package.json +1 -1
- package/src/agentcore-gateway/agent-connection/schema.json +31 -0
- package/src/agentcore-gateway/gateway-connection/schema.json +31 -0
- package/src/agentcore-gateway/mcp-connection/schema.json +31 -0
- package/src/agentcore-gateway/react-connection/schema.json +31 -0
- package/src/agentcore-gateway/schema.json +72 -0
- package/src/agentcore-harness/schema.json +53 -0
- package/src/connection/schema.json +5 -0
- package/src/infra/app/schema.json +5 -0
- package/src/init/schema.json +35 -0
- package/src/internal/test-matrix/schema.json +21 -0
- package/src/license/schema.json +5 -0
- package/src/open-api/json-metadata/schema.json +20 -0
- package/src/preset/schema.json +16 -5
- package/src/py/agent/a2a-connection/schema.json +5 -0
- package/src/py/agent/gateway-connection/schema.json +31 -0
- package/src/py/agent/mcp-connection/schema.json +5 -0
- package/src/py/agent/react-connection/schema.json +5 -0
- package/src/py/agent/schema.json +15 -1
- package/src/py/api/schema.json +5 -0
- package/src/py/dynamodb/agent-connection/schema.json +27 -0
- package/src/py/dynamodb/fast-api-connection/schema.json +23 -0
- package/src/py/dynamodb/mcp-server-connection/schema.json +27 -0
- package/src/py/dynamodb/schema.json +76 -0
- package/src/py/fast-api/react/schema.json +5 -0
- package/src/py/fast-api/schema.json +6 -0
- package/src/py/lambda-function/schema.json +6 -1
- package/src/py/mcp-server/schema.json +6 -0
- package/src/py/project/schema.json +6 -0
- package/src/py/rdb/agent-connection/schema.json +27 -0
- package/src/py/rdb/fast-api-connection/schema.json +23 -0
- package/src/py/rdb/mcp-server-connection/schema.json +27 -0
- package/src/py/rdb/schema.json +78 -0
- package/src/smithy/project/schema.json +28 -1
- package/src/smithy/react-connection/schema.json +5 -0
- package/src/smithy/ts/api/schema.json +6 -0
- package/src/terraform/project/schema.json +5 -0
- package/src/trpc/backend/schema.json +6 -0
- package/src/trpc/react/schema.json +5 -0
- package/src/ts/agent/a2a-connection/schema.json +5 -0
- package/src/ts/agent/gateway-connection/schema.json +31 -0
- package/src/ts/agent/mcp-connection/schema.json +5 -0
- package/src/ts/agent/react-connection/schema.json +5 -0
- package/src/ts/agent/schema.json +14 -0
- package/src/ts/api/schema.json +5 -0
- package/src/ts/astro-docs/schema.json +3 -3
- package/src/ts/dcr-proxy/schema.json +44 -0
- package/src/ts/docs/schema.json +3 -3
- package/src/ts/dynamodb/agent-connection/schema.json +5 -0
- package/src/ts/dynamodb/mcp-server-connection/schema.json +5 -0
- package/src/ts/dynamodb/schema.json +26 -2
- package/src/ts/dynamodb/smithy-connection/schema.json +5 -0
- package/src/ts/dynamodb/trpc-connection/schema.json +5 -0
- package/src/ts/lambda-function/schema.json +5 -0
- package/src/ts/lib/schema.json +5 -0
- package/src/ts/mcp-server/schema.json +6 -0
- package/src/ts/nx-generator/schema.json +5 -0
- package/src/ts/nx-migration/schema.json +63 -0
- package/src/ts/nx-plugin/schema.json +5 -0
- package/src/ts/rdb/agent-connection/schema.json +5 -0
- package/src/ts/rdb/mcp-server-connection/schema.json +5 -0
- package/src/ts/rdb/schema.json +7 -1
- package/src/ts/rdb/smithy-connection/schema.json +5 -0
- package/src/ts/rdb/trpc-connection/schema.json +5 -0
- package/src/ts/react-website/app/schema.json +12 -6
- package/src/ts/react-website/cognito-auth/schema.json +5 -0
- package/src/ts/react-website/runtime-config/schema.json +5 -0
- package/src/ts/website/app/schema.json +11 -6
- package/src/ts/website/auth/schema.json +5 -0
- /package/docs/snippets/connection/{lambda-rdb-ssl-requirements.mdx → ts-lambda-rdb-ssl-requirements.mdx} +0 -0
- /package/docs/snippets/connection/{mcp-server-rdb-ssl-requirements.mdx → ts-mcp-server-rdb-ssl-requirements.mdx} +0 -0
|
@@ -1,24 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Type-Safe API Integrations
|
|
3
3
|
---
|
|
4
|
-
import {
|
|
4
|
+
import { Steps } from '@astrojs/starlight/components';
|
|
5
5
|
import Infrastructure from '@components/infrastructure.astro';
|
|
6
|
+
import Drawer from '@components/drawer.astro';
|
|
7
|
+
import OptionFilter from '@components/option-filter.astro';
|
|
8
|
+
import RunGenerator from '@components/run-generator.astro';
|
|
6
9
|
|
|
7
10
|
The REST/HTTP API CDK constructs are configured to provide a type-safe interface for defining integrations for each of your operations.
|
|
8
11
|
|
|
9
|
-
<Infrastructure>
|
|
10
|
-
<Fragment slot="cdk">
|
|
11
|
-
The CDK constructs provide full type-safe integration support as described below.
|
|
12
|
-
</Fragment>
|
|
13
|
-
<Fragment slot="terraform">
|
|
14
|
-
:::note[Router Pattern]
|
|
15
|
-
Terraform modules use the "router pattern" with a single Lambda function serving all operations. Type-safe integrations are not supported - the module creates one Lambda function that handles all API requests.
|
|
16
|
-
|
|
17
|
-
For explicit per-operation integrations with Terraform, you would need to manually create individual Lambda functions and API Gateway routes. See the [Explicit Integrations](#explicit-integrations) section for examples.
|
|
18
|
-
:::
|
|
19
|
-
</Fragment>
|
|
20
|
-
</Infrastructure>
|
|
21
|
-
|
|
22
12
|
#### Default Integrations
|
|
23
13
|
|
|
24
14
|
<Infrastructure>
|
|
@@ -32,7 +22,7 @@ new MyApi(this, 'MyApi', {
|
|
|
32
22
|
```
|
|
33
23
|
</Fragment>
|
|
34
24
|
<Fragment slot="terraform">
|
|
35
|
-
|
|
25
|
+
The generated module already defines the default integrations for the pattern the API was generated with, so no additional configuration is needed:
|
|
36
26
|
|
|
37
27
|
```hcl
|
|
38
28
|
module "my_api" {
|
|
@@ -40,11 +30,11 @@ module "my_api" {
|
|
|
40
30
|
|
|
41
31
|
asset_bucket_name = module.asset_bucket.bucket_name
|
|
42
32
|
|
|
43
|
-
# The module automatically creates a single Lambda function
|
|
44
|
-
# that handles all API operations
|
|
45
33
|
tags = local.common_tags
|
|
46
34
|
}
|
|
47
35
|
```
|
|
36
|
+
|
|
37
|
+
With the default `isolated` pattern, this creates one Lambda function per operation.
|
|
48
38
|
</Fragment>
|
|
49
39
|
</Infrastructure>
|
|
50
40
|
|
|
@@ -69,7 +59,7 @@ api.integrations.sayHello.handler.addToRolePolicy(new PolicyStatement({
|
|
|
69
59
|
|
|
70
60
|
If your API uses the `shared` pattern, the shared router Lambda is exposed as `api.integrations.$router`:
|
|
71
61
|
|
|
72
|
-
```ts {
|
|
62
|
+
```ts {5}
|
|
73
63
|
const api = new MyApi(this, 'MyApi', {
|
|
74
64
|
integrations: MyApi.defaultIntegrations(this).build(),
|
|
75
65
|
});
|
|
@@ -78,13 +68,13 @@ api.integrations.$router.handler.addEnvironment('LOG_LEVEL', 'DEBUG');
|
|
|
78
68
|
```
|
|
79
69
|
</Fragment>
|
|
80
70
|
<Fragment slot="terraform">
|
|
81
|
-
With
|
|
71
|
+
With the `isolated` pattern, the module's outputs are maps keyed by operation name, so you can reach a single operation's resources. For example, to grant one operation's Lambda function extra permissions:
|
|
82
72
|
|
|
83
73
|
```hcl
|
|
84
|
-
# Grant additional permissions to the
|
|
85
|
-
resource "aws_iam_role_policy" "
|
|
86
|
-
name = "additional-
|
|
87
|
-
role = module.my_api.
|
|
74
|
+
# Grant additional permissions to just the sayHello operation's function
|
|
75
|
+
resource "aws_iam_role_policy" "say_hello_permissions" {
|
|
76
|
+
name = "say-hello-additional-permissions"
|
|
77
|
+
role = module.my_api.lambda_execution_role_names["sayHello"]
|
|
88
78
|
|
|
89
79
|
policy = jsonencode({
|
|
90
80
|
Version = "2012-10-17"
|
|
@@ -101,6 +91,48 @@ resource "aws_iam_role_policy" "additional_permissions" {
|
|
|
101
91
|
})
|
|
102
92
|
}
|
|
103
93
|
```
|
|
94
|
+
|
|
95
|
+
To grant the same permissions to every operation, iterate the `operations` output:
|
|
96
|
+
|
|
97
|
+
```hcl
|
|
98
|
+
resource "aws_iam_role_policy" "additional_permissions" {
|
|
99
|
+
for_each = toset(module.my_api.operations)
|
|
100
|
+
|
|
101
|
+
name = "additional-api-permissions"
|
|
102
|
+
role = module.my_api.lambda_execution_role_names[each.key]
|
|
103
|
+
|
|
104
|
+
policy = jsonencode({
|
|
105
|
+
Version = "2012-10-17"
|
|
106
|
+
Statement = [
|
|
107
|
+
{
|
|
108
|
+
Effect = "Allow"
|
|
109
|
+
Action = ["s3:GetObject"]
|
|
110
|
+
Resource = "arn:aws:s3:::my-bucket/*"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The module also exposes `lambda_function_names`, `lambda_function_arns`, `lambda_invoke_arns`, `integration_ids` and `lambda_log_group_names` as maps keyed by operation name. With the `shared` pattern the equivalent singular outputs (`lambda_execution_role_name`, `lambda_function_name`, …) are exposed instead, since there is only one function.
|
|
118
|
+
|
|
119
|
+
Permissions every operation needs are better passed to the module, which applies them to each function's role:
|
|
120
|
+
|
|
121
|
+
```hcl
|
|
122
|
+
module "my_api" {
|
|
123
|
+
source = "../../common/terraform/src/app/apis/my-api"
|
|
124
|
+
|
|
125
|
+
asset_bucket_name = module.asset_bucket.bucket_name
|
|
126
|
+
|
|
127
|
+
additional_iam_policy_statements = [
|
|
128
|
+
{
|
|
129
|
+
Effect = "Allow"
|
|
130
|
+
Action = ["s3:GetObject"]
|
|
131
|
+
Resource = ["arn:aws:s3:::my-bucket/*"]
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
```
|
|
104
136
|
</Fragment>
|
|
105
137
|
</Infrastructure>
|
|
106
138
|
|
|
@@ -125,48 +157,67 @@ new MyApi(this, 'MyApi', {
|
|
|
125
157
|
|
|
126
158
|
</Fragment>
|
|
127
159
|
<Fragment slot="terraform">
|
|
128
|
-
|
|
160
|
+
VPC configuration is already supported by the generated module — set `enable_vpc` along with `vpc_id` and `subnet_ids`, and the module deploys every Lambda function into your VPC behind a shared security group it creates for you:
|
|
129
161
|
|
|
130
162
|
```hcl
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
variable "vpc_subnet_ids" {
|
|
134
|
-
description = "List of VPC subnet IDs for Lambda function"
|
|
135
|
-
type = list(string)
|
|
136
|
-
default = []
|
|
137
|
-
}
|
|
163
|
+
module "my_api" {
|
|
164
|
+
source = "../../common/terraform/src/app/apis/my-api"
|
|
138
165
|
|
|
139
|
-
|
|
140
|
-
description = "List of VPC security group IDs for Lambda function"
|
|
141
|
-
type = list(string)
|
|
142
|
-
default = []
|
|
143
|
-
}
|
|
166
|
+
asset_bucket_name = module.asset_bucket.bucket_name
|
|
144
167
|
|
|
145
|
-
#
|
|
146
|
-
|
|
147
|
-
|
|
168
|
+
# VPC configuration
|
|
169
|
+
enable_vpc = true
|
|
170
|
+
vpc_id = aws_vpc.main.id
|
|
171
|
+
subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
|
|
148
172
|
|
|
149
|
-
|
|
150
|
-
vpc_config {
|
|
151
|
-
subnet_ids = var.vpc_subnet_ids
|
|
152
|
-
security_group_ids = var.vpc_security_group_ids
|
|
153
|
-
}
|
|
173
|
+
tags = local.common_tags
|
|
154
174
|
}
|
|
155
175
|
```
|
|
156
176
|
|
|
157
|
-
|
|
177
|
+
For options the module does not expose, edit the `aws_lambda_function` resource in the generated Terraform module directly. With the `isolated` pattern that single resource is declared `for_each = local.operations`, so an edit there applies to every operation.
|
|
178
|
+
</Fragment>
|
|
179
|
+
</Infrastructure>
|
|
158
180
|
|
|
159
|
-
|
|
160
|
-
module "my_api" {
|
|
161
|
-
source = "../../common/terraform/src/app/apis/my-api"
|
|
181
|
+
#### Customising Options Per-Operation
|
|
162
182
|
|
|
163
|
-
|
|
183
|
+
<Infrastructure>
|
|
184
|
+
<Fragment slot="cdk">
|
|
185
|
+
To customise the options used to create the default integration for _specific_ operations (without affecting the others), you can use the `withOperationOptions` method. For example, if you would like to increase the Lambda function timeout for just one operation:
|
|
164
186
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
187
|
+
```ts {4-6}
|
|
188
|
+
const api = new MyApi(this, 'MyApi', {
|
|
189
|
+
integrations: MyApi.defaultIntegrations(this)
|
|
190
|
+
.withOperationOptions({
|
|
191
|
+
sayHello: {
|
|
192
|
+
timeout: Duration.seconds(60),
|
|
193
|
+
},
|
|
194
|
+
})
|
|
195
|
+
.build(),
|
|
196
|
+
});
|
|
168
197
|
|
|
169
|
-
|
|
198
|
+
// The selected operations remain default integrations, so they're still typed accordingly:
|
|
199
|
+
api.integrations.sayHello.handler.addToRolePolicy(new PolicyStatement({ ... }));
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The options you specify are merged with the default integration options (and any options set via `withDefaultOptions`). Note that you cannot specify options for operations which you have replaced via `withOverrides`, since these no longer use the default integration.
|
|
203
|
+
|
|
204
|
+
You will encounter a type error if the same operation is targeted by both `withOperationOptions` and `withOverrides`, regardless of the order in which you call them.
|
|
205
|
+
|
|
206
|
+
</Fragment>
|
|
207
|
+
<Fragment slot="terraform">
|
|
208
|
+
With the `isolated` pattern the Lambda function resource is already per-operation, so options can be varied by operation name. For example, to give one operation a longer timeout, edit the `aws_lambda_function` resource in the generated module:
|
|
209
|
+
|
|
210
|
+
```hcl
|
|
211
|
+
# packages/common/terraform/src/app/apis/my-api/my-api.tf
|
|
212
|
+
resource "aws_lambda_function" "api_lambda" {
|
|
213
|
+
for_each = local.operations
|
|
214
|
+
|
|
215
|
+
# Default to 30 seconds, but allow longer for specific operations
|
|
216
|
+
timeout = lookup({
|
|
217
|
+
sayHello = 60
|
|
218
|
+
}, each.key, 30)
|
|
219
|
+
|
|
220
|
+
# ... rest of configuration
|
|
170
221
|
}
|
|
171
222
|
```
|
|
172
223
|
</Fragment>
|
|
@@ -239,11 +290,36 @@ api.integrations.getFile.bucket.grantRead(...);
|
|
|
239
290
|
```
|
|
240
291
|
</Fragment>
|
|
241
292
|
<Fragment slot="terraform">
|
|
242
|
-
|
|
243
|
-
Overriding specific integrations is not supported with Terraform modules since they use the router pattern. All operations are handled by the single Lambda function.
|
|
293
|
+
To point a specific operation at a different integration type, exclude it from the default `for_each` and declare its integration separately. For example, to serve `getDocumentation` from an external website:
|
|
244
294
|
|
|
245
|
-
|
|
246
|
-
|
|
295
|
+
```hcl
|
|
296
|
+
# packages/common/terraform/src/app/apis/my-api/my-api.tf
|
|
297
|
+
|
|
298
|
+
# Exclude the overridden operation from the default per-operation resources
|
|
299
|
+
locals {
|
|
300
|
+
overridden_operations = ["getDocumentation"]
|
|
301
|
+
default_operations = {
|
|
302
|
+
for op, details in local.operations : op => details
|
|
303
|
+
if !contains(local.overridden_operations, op)
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
# Then use local.default_operations in place of local.operations for the
|
|
308
|
+
# aws_lambda_function, aws_iam_role, aws_apigatewayv2_integration and
|
|
309
|
+
# aws_lambda_permission resources, and add the override:
|
|
310
|
+
resource "aws_apigatewayv2_integration" "get_documentation" {
|
|
311
|
+
api_id = module.http_api.api_id
|
|
312
|
+
integration_type = "HTTP_PROXY"
|
|
313
|
+
integration_uri = "https://example.com/documentation"
|
|
314
|
+
integration_method = "GET"
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
resource "aws_apigatewayv2_route" "get_documentation" {
|
|
318
|
+
api_id = module.http_api.api_id
|
|
319
|
+
route_key = local.route_key["getDocumentation"]
|
|
320
|
+
target = "integrations/${aws_apigatewayv2_integration.get_documentation.id}"
|
|
321
|
+
}
|
|
322
|
+
```
|
|
247
323
|
</Fragment>
|
|
248
324
|
</Infrastructure>
|
|
249
325
|
|
|
@@ -269,11 +345,20 @@ new MyApi(this, 'MyApi', {
|
|
|
269
345
|
```
|
|
270
346
|
</Fragment>
|
|
271
347
|
<Fragment slot="terraform">
|
|
272
|
-
|
|
273
|
-
Per-operation authorizer overrides are not supported with Terraform modules. The entire API uses the authentication method specified when generating the API (IAM, Cognito, or Custom).
|
|
348
|
+
Authorization is set on the route (HTTP API) or method (REST API) for each operation, so it can be varied by operation name. For example, to leave one operation unauthenticated on an HTTP API:
|
|
274
349
|
|
|
275
|
-
|
|
276
|
-
|
|
350
|
+
```hcl
|
|
351
|
+
# packages/common/terraform/src/app/apis/my-api/my-api.tf
|
|
352
|
+
resource "aws_apigatewayv2_route" "operation_routes" {
|
|
353
|
+
for_each = local.operations
|
|
354
|
+
|
|
355
|
+
# ... rest of configuration
|
|
356
|
+
|
|
357
|
+
authorization_type = each.key == "getDocumentation" ? "NONE" : "AWS_IAM"
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
For an IAM-authenticated REST API, also add a resource policy statement allowing unauthenticated access to that operation's path.
|
|
277
362
|
</Fragment>
|
|
278
363
|
</Infrastructure>
|
|
279
364
|
|
|
@@ -297,319 +382,28 @@ new MyApi(this, 'MyApi', {
|
|
|
297
382
|
```
|
|
298
383
|
</Fragment>
|
|
299
384
|
<Fragment slot="terraform">
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
Edit `packages/common/terraform/src/app/apis/my-api/my-api.tf`:
|
|
303
|
-
|
|
304
|
-
1. **Remove the default proxy routes** (e.g., `resource "aws_apigatewayv2_route" "proxy_routes"`)
|
|
305
|
-
2. **Replace the single Lambda function** with individual functions for each operation
|
|
306
|
-
3. **Create specific integrations and routes** for each operation, reusing the same ZIP bundle:
|
|
307
|
-
|
|
308
|
-
<Tabs syncKey="http-rest">
|
|
309
|
-
<TabItem label="HTTP API" _filter={{ infra: 'http-lambda' }}>
|
|
310
|
-
|
|
311
|
-
```diff
|
|
312
|
-
# packages/common/terraform/src/app/apis/my-api/my-api.tf
|
|
313
|
-
|
|
314
|
-
# Remove the default single Lambda function
|
|
315
|
-
- resource "aws_lambda_function" "api_lambda" {
|
|
316
|
-
- filename = data.archive_file.lambda_zip.output_path
|
|
317
|
-
- function_name = "MyApiHandler"
|
|
318
|
-
- role = aws_iam_role.lambda_execution_role.arn
|
|
319
|
-
- handler = "index.handler"
|
|
320
|
-
- runtime = "nodejs22.x"
|
|
321
|
-
- timeout = 30
|
|
322
|
-
- # ... rest of configuration
|
|
323
|
-
- }
|
|
324
|
-
|
|
325
|
-
# Remove the default proxy integration
|
|
326
|
-
- resource "aws_apigatewayv2_integration" "lambda_integration" {
|
|
327
|
-
- api_id = module.http_api.api_id
|
|
328
|
-
- integration_type = "AWS_PROXY"
|
|
329
|
-
- integration_uri = aws_lambda_function.api_lambda.invoke_arn
|
|
330
|
-
- # ... rest of configuration
|
|
331
|
-
- }
|
|
332
|
-
|
|
333
|
-
# Remove the default proxy routes
|
|
334
|
-
- resource "aws_apigatewayv2_route" "proxy_routes" {
|
|
335
|
-
- for_each = toset(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"])
|
|
336
|
-
- api_id = module.http_api.api_id
|
|
337
|
-
- route_key = "${each.key} /{proxy+}"
|
|
338
|
-
- target = "integrations/${aws_apigatewayv2_integration.lambda_integration.id}"
|
|
339
|
-
- # ... rest of configuration
|
|
340
|
-
- }
|
|
341
|
-
|
|
342
|
-
# Add individual Lambda functions for each operation using the same bundle
|
|
343
|
-
+ resource "aws_lambda_function" "say_hello_handler" {
|
|
344
|
-
+ filename = data.archive_file.lambda_zip.output_path
|
|
345
|
-
+ function_name = "MyApi-SayHello"
|
|
346
|
-
+ role = aws_iam_role.lambda_execution_role.arn
|
|
347
|
-
+ handler = "sayHello.handler" # Specific handler for this operation
|
|
348
|
-
+ runtime = "nodejs22.x"
|
|
349
|
-
+ timeout = 30
|
|
350
|
-
+ source_code_hash = data.archive_file.lambda_zip.output_base64sha256
|
|
351
|
-
+
|
|
352
|
-
+ tracing_config {
|
|
353
|
-
+ mode = "Active"
|
|
354
|
-
+ }
|
|
355
|
-
+
|
|
356
|
-
+ environment {
|
|
357
|
-
+ variables = var.env
|
|
358
|
-
+ }
|
|
359
|
-
+
|
|
360
|
-
+ tags = var.tags
|
|
361
|
-
+ }
|
|
362
|
-
|
|
363
|
-
+ resource "aws_lambda_function" "get_documentation_handler" {
|
|
364
|
-
+ filename = data.archive_file.lambda_zip.output_path
|
|
365
|
-
+ function_name = "MyApi-GetDocumentation"
|
|
366
|
-
+ role = aws_iam_role.lambda_execution_role.arn
|
|
367
|
-
+ handler = "getDocumentation.handler" # Specific handler for this operation
|
|
368
|
-
+ runtime = "nodejs22.x"
|
|
369
|
-
+ timeout = 30
|
|
370
|
-
+ source_code_hash = data.archive_file.lambda_zip.output_base64sha256
|
|
371
|
-
+
|
|
372
|
-
+ tracing_config {
|
|
373
|
-
+ mode = "Active"
|
|
374
|
-
+ }
|
|
375
|
-
+
|
|
376
|
-
+ environment {
|
|
377
|
-
+ variables = var.env
|
|
378
|
-
+ }
|
|
379
|
-
+
|
|
380
|
-
+ tags = var.tags
|
|
381
|
-
+ }
|
|
382
|
-
|
|
383
|
-
# Add specific integrations for each operation
|
|
384
|
-
+ resource "aws_apigatewayv2_integration" "say_hello_integration" {
|
|
385
|
-
+ api_id = module.http_api.api_id
|
|
386
|
-
+ integration_type = "AWS_PROXY"
|
|
387
|
-
+ integration_uri = aws_lambda_function.say_hello_handler.invoke_arn
|
|
388
|
-
+ payload_format_version = "2.0"
|
|
389
|
-
+ timeout_milliseconds = 30000
|
|
390
|
-
+ }
|
|
391
|
-
|
|
392
|
-
+ resource "aws_apigatewayv2_integration" "get_documentation_integration" {
|
|
393
|
-
+ api_id = module.http_api.api_id
|
|
394
|
-
+ integration_type = "HTTP_PROXY"
|
|
395
|
-
+ integration_uri = "https://example.com/documentation"
|
|
396
|
-
+ integration_method = "GET"
|
|
397
|
-
+ }
|
|
398
|
-
|
|
399
|
-
# Add specific routes for each operation
|
|
400
|
-
+ resource "aws_apigatewayv2_route" "say_hello_route" {
|
|
401
|
-
+ api_id = module.http_api.api_id
|
|
402
|
-
+ route_key = "POST /sayHello"
|
|
403
|
-
+ target = "integrations/${aws_apigatewayv2_integration.say_hello_integration.id}"
|
|
404
|
-
+ authorization_type = "AWS_IAM"
|
|
405
|
-
+ }
|
|
406
|
-
|
|
407
|
-
+ resource "aws_apigatewayv2_route" "get_documentation_route" {
|
|
408
|
-
+ api_id = module.http_api.api_id
|
|
409
|
-
+ route_key = "GET /documentation"
|
|
410
|
-
+ target = "integrations/${aws_apigatewayv2_integration.get_documentation_integration.id}"
|
|
411
|
-
+ authorization_type = "NONE"
|
|
412
|
-
+ }
|
|
413
|
-
|
|
414
|
-
# Add Lambda permissions for each function
|
|
415
|
-
+ resource "aws_lambda_permission" "say_hello_permission" {
|
|
416
|
-
+ statement_id = "AllowExecutionFromAPIGateway-SayHello"
|
|
417
|
-
+ action = "lambda:InvokeFunction"
|
|
418
|
-
+ function_name = aws_lambda_function.say_hello_handler.function_name
|
|
419
|
-
+ principal = "apigateway.amazonaws.com"
|
|
420
|
-
+ source_arn = "${module.http_api.api_execution_arn}/*/*"
|
|
421
|
-
+ }
|
|
422
|
-
|
|
423
|
-
+ resource "aws_lambda_permission" "get_documentation_permission" {
|
|
424
|
-
+ statement_id = "AllowExecutionFromAPIGateway-GetDocumentation"
|
|
425
|
-
+ action = "lambda:InvokeFunction"
|
|
426
|
-
+ function_name = aws_lambda_function.get_documentation_handler.function_name
|
|
427
|
-
+ principal = "apigateway.amazonaws.com"
|
|
428
|
-
+ source_arn = "${module.http_api.api_execution_arn}/*/*"
|
|
429
|
-
+ }
|
|
430
|
-
```
|
|
431
|
-
</TabItem>
|
|
432
|
-
<TabItem label="REST API" _filter={{ infra: 'rest-lambda' }}>
|
|
433
|
-
|
|
434
|
-
```diff
|
|
435
|
-
# packages/common/terraform/src/app/apis/my-api/my-api.tf
|
|
436
|
-
|
|
437
|
-
# Remove the default single Lambda function
|
|
438
|
-
- resource "aws_lambda_function" "api_lambda" {
|
|
439
|
-
- filename = data.archive_file.lambda_zip.output_path
|
|
440
|
-
- function_name = "MyApiHandler"
|
|
441
|
-
- role = aws_iam_role.lambda_execution_role.arn
|
|
442
|
-
- handler = "index.handler"
|
|
443
|
-
- runtime = "nodejs22.x"
|
|
444
|
-
- timeout = 30
|
|
445
|
-
- # ... rest of configuration
|
|
446
|
-
- }
|
|
447
|
-
|
|
448
|
-
# Remove the default proxy integration
|
|
449
|
-
- resource "aws_apigatewayv2_integration" "lambda_integration" {
|
|
450
|
-
- api_id = module.http_api.api_id
|
|
451
|
-
- integration_type = "AWS_PROXY"
|
|
452
|
-
- integration_uri = aws_lambda_function.api_lambda.invoke_arn
|
|
453
|
-
- # ... rest of configuration
|
|
454
|
-
- }
|
|
455
|
-
|
|
456
|
-
# Remove the default proxy routes
|
|
457
|
-
- resource "aws_apigatewayv2_route" "proxy_routes" {
|
|
458
|
-
- for_each = toset(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"])
|
|
459
|
-
- api_id = module.http_api.api_id
|
|
460
|
-
- route_key = "${each.key} /{proxy+}"
|
|
461
|
-
- target = "integrations/${aws_apigatewayv2_integration.lambda_integration.id}"
|
|
462
|
-
- # ... rest of configuration
|
|
463
|
-
- }
|
|
464
|
-
|
|
465
|
-
# Add individual Lambda functions for each operation using the same bundle
|
|
466
|
-
+ resource "aws_lambda_function" "say_hello_handler" {
|
|
467
|
-
+ filename = data.archive_file.lambda_zip.output_path
|
|
468
|
-
+ function_name = "MyApi-SayHello"
|
|
469
|
-
+ role = aws_iam_role.lambda_execution_role.arn
|
|
470
|
-
+ handler = "sayHello.handler" # Specific handler for this operation
|
|
471
|
-
+ runtime = "nodejs22.x"
|
|
472
|
-
+ timeout = 30
|
|
473
|
-
+ source_code_hash = data.archive_file.lambda_zip.output_base64sha256
|
|
474
|
-
+
|
|
475
|
-
+ tracing_config {
|
|
476
|
-
+ mode = "Active"
|
|
477
|
-
+ }
|
|
478
|
-
+
|
|
479
|
-
+ environment {
|
|
480
|
-
+ variables = var.env
|
|
481
|
-
+ }
|
|
482
|
-
+
|
|
483
|
-
+ tags = var.tags
|
|
484
|
-
+ }
|
|
485
|
-
|
|
486
|
-
+ resource "aws_lambda_function" "get_documentation_handler" {
|
|
487
|
-
+ filename = data.archive_file.lambda_zip.output_path
|
|
488
|
-
+ function_name = "MyApi-GetDocumentation"
|
|
489
|
-
+ role = aws_iam_role.lambda_execution_role.arn
|
|
490
|
-
+ handler = "getDocumentation.handler" # Specific handler for this operation
|
|
491
|
-
+ runtime = "nodejs22.x"
|
|
492
|
-
+ timeout = 30
|
|
493
|
-
+ source_code_hash = data.archive_file.lambda_zip.output_base64sha256
|
|
494
|
-
+
|
|
495
|
-
+ tracing_config {
|
|
496
|
-
+ mode = "Active"
|
|
497
|
-
+ }
|
|
498
|
-
+
|
|
499
|
-
+ environment {
|
|
500
|
-
+ variables = var.env
|
|
501
|
-
+ }
|
|
502
|
-
+
|
|
503
|
-
+ tags = var.tags
|
|
504
|
-
+ }
|
|
505
|
-
|
|
506
|
-
# Add specific resources and methods for each operation
|
|
507
|
-
+ resource "aws_api_gateway_resource" "say_hello_resource" {
|
|
508
|
-
+ rest_api_id = module.rest_api.api_id
|
|
509
|
-
+ parent_id = module.rest_api.api_root_resource_id
|
|
510
|
-
+ path_part = "sayHello"
|
|
511
|
-
+ }
|
|
512
|
-
|
|
513
|
-
+ resource "aws_api_gateway_method" "say_hello_method" {
|
|
514
|
-
+ rest_api_id = module.rest_api.api_id
|
|
515
|
-
+ resource_id = aws_api_gateway_resource.say_hello_resource.id
|
|
516
|
-
+ http_method = "POST"
|
|
517
|
-
+ authorization = "AWS_IAM"
|
|
518
|
-
+ }
|
|
519
|
-
|
|
520
|
-
+ resource "aws_api_gateway_integration" "say_hello_integration" {
|
|
521
|
-
+ rest_api_id = module.rest_api.api_id
|
|
522
|
-
+ resource_id = aws_api_gateway_resource.say_hello_resource.id
|
|
523
|
-
+ http_method = aws_api_gateway_method.say_hello_method.http_method
|
|
524
|
-
+
|
|
525
|
-
+ integration_http_method = "POST"
|
|
526
|
-
+ type = "AWS_PROXY"
|
|
527
|
-
+ uri = aws_lambda_function.say_hello_handler.invoke_arn
|
|
528
|
-
+ }
|
|
529
|
-
|
|
530
|
-
+ resource "aws_api_gateway_resource" "get_documentation_resource" {
|
|
531
|
-
+ rest_api_id = module.rest_api.api_id
|
|
532
|
-
+ parent_id = module.rest_api.api_root_resource_id
|
|
533
|
-
+ path_part = "documentation"
|
|
534
|
-
+ }
|
|
535
|
-
|
|
536
|
-
+ resource "aws_api_gateway_method" "get_documentation_method" {
|
|
537
|
-
+ rest_api_id = module.rest_api.api_id
|
|
538
|
-
+ resource_id = aws_api_gateway_resource.get_documentation_resource.id
|
|
539
|
-
+ http_method = "GET"
|
|
540
|
-
+ authorization = "NONE"
|
|
541
|
-
+ }
|
|
542
|
-
|
|
543
|
-
+ resource "aws_api_gateway_integration" "get_documentation_integration" {
|
|
544
|
-
+ rest_api_id = module.rest_api.api_id
|
|
545
|
-
+ resource_id = aws_api_gateway_resource.get_documentation_resource.id
|
|
546
|
-
+ http_method = aws_api_gateway_method.get_documentation_method.http_method
|
|
547
|
-
+
|
|
548
|
-
+ integration_http_method = "GET"
|
|
549
|
-
+ type = "HTTP"
|
|
550
|
-
+ uri = "https://example.com/documentation"
|
|
551
|
-
+ }
|
|
552
|
-
|
|
553
|
-
# Update deployment to depend on new integrations
|
|
554
|
-
~ resource "aws_api_gateway_deployment" "api_deployment" {
|
|
555
|
-
rest_api_id = module.rest_api.api_id
|
|
556
|
-
|
|
557
|
-
depends_on = [
|
|
558
|
-
- aws_api_gateway_integration.lambda_integration,
|
|
559
|
-
+ aws_api_gateway_integration.say_hello_integration,
|
|
560
|
-
+ aws_api_gateway_integration.get_documentation_integration,
|
|
561
|
-
]
|
|
562
|
-
|
|
563
|
-
lifecycle {
|
|
564
|
-
create_before_destroy = true
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
+ triggers = {
|
|
568
|
-
+ redeployment = sha1(jsonencode([
|
|
569
|
-
+ aws_api_gateway_integration.say_hello_integration,
|
|
570
|
-
+ aws_api_gateway_integration.get_documentation_integration,
|
|
571
|
-
+ ]))
|
|
572
|
-
+ }
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
# Add Lambda permissions for each function
|
|
576
|
-
+ resource "aws_lambda_permission" "say_hello_permission" {
|
|
577
|
-
+ statement_id = "AllowExecutionFromAPIGateway-SayHello"
|
|
578
|
-
+ action = "lambda:InvokeFunction"
|
|
579
|
-
+ function_name = aws_lambda_function.say_hello_handler.function_name
|
|
580
|
-
+ principal = "apigateway.amazonaws.com"
|
|
581
|
-
+ source_arn = "${module.rest_api.api_execution_arn}/*/*"
|
|
582
|
-
+ }
|
|
583
|
-
|
|
584
|
-
+ resource "aws_lambda_permission" "get_documentation_permission" {
|
|
585
|
-
+ statement_id = "AllowExecutionFromAPIGateway-GetDocumentation"
|
|
586
|
-
+ action = "lambda:InvokeFunction"
|
|
587
|
-
+ function_name = aws_lambda_function.get_documentation_handler.function_name
|
|
588
|
-
+ principal = "apigateway.amazonaws.com"
|
|
589
|
-
+ source_arn = "${module.rest_api.api_execution_arn}/*/*"
|
|
590
|
-
+ }
|
|
591
|
-
```
|
|
592
|
-
</TabItem>
|
|
593
|
-
</Tabs>
|
|
385
|
+
Replace the `for_each` used by the `isolated` pattern with explicit instantiations of the Lambda functions, integrations and permissions for each operation.
|
|
594
386
|
|
|
387
|
+
:::caution
|
|
388
|
+
Unlike CDK, there is no type-safety in Terraform which will give you a type error if you add a new operation in your application code but forget to declare it in your infrastructure.
|
|
389
|
+
:::
|
|
595
390
|
</Fragment>
|
|
596
391
|
</Infrastructure>
|
|
597
392
|
|
|
598
393
|
#### Integration Pattern
|
|
599
394
|
|
|
600
|
-
|
|
601
|
-
<Fragment slot="cdk">
|
|
395
|
+
Generated APIs support two integration patterns:
|
|
602
396
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
- `isolated` creates one Lambda function per operation. This is the default for generated APIs.
|
|
397
|
+
- `isolated` creates one Lambda function per operation. This is the default and recommended option for APIs.
|
|
606
398
|
- `shared` creates a single default router Lambda and reuses it for every operation unless you override specific integrations.
|
|
607
399
|
|
|
608
|
-
`isolated` gives you finer-grained permissions and configuration per operation. `shared` reduces
|
|
400
|
+
`isolated` gives you finer-grained permissions and configuration per operation, as well as better separation for logs and traces. `shared` reduces the likelihood of encountering cold-starts for low-usage APIs.
|
|
609
401
|
|
|
610
|
-
|
|
402
|
+
<Infrastructure>
|
|
403
|
+
<Fragment slot="cdk">
|
|
404
|
+
The integration pattern can be changed at any time in CDK by updating your API construct. For example, setting `pattern` to `'shared'` creates a single function instead of one per integration:
|
|
611
405
|
|
|
612
|
-
```ts {
|
|
406
|
+
```ts {6}
|
|
613
407
|
// packages/common/constructs/src/app/apis/my-api.ts
|
|
614
408
|
export class MyApi<...> extends ... {
|
|
615
409
|
|
|
@@ -624,20 +418,71 @@ export class MyApi<...> extends ... {
|
|
|
624
418
|
```
|
|
625
419
|
</Fragment>
|
|
626
420
|
<Fragment slot="terraform">
|
|
627
|
-
|
|
421
|
+
Unlike CDK, the integration pattern is baked into the generated module. To change the integration pattern:
|
|
628
422
|
|
|
629
|
-
|
|
423
|
+
<Steps>
|
|
424
|
+
1. Delete the previously generated API module in `packages/common/terraform/src/app/apis`
|
|
425
|
+
2. Re-run the API generator with the other integration pattern:
|
|
426
|
+
<RunGenerator generator="ts#api" requiredParameters={{ integrationPattern: 'shared' }} />
|
|
427
|
+
</Steps>
|
|
630
428
|
|
|
631
|
-
|
|
632
|
-
# Default router pattern - single Lambda function for all operations
|
|
633
|
-
module "my_api" {
|
|
634
|
-
source = "../../common/terraform/src/app/apis/my-api"
|
|
429
|
+
With the `isolated` pattern, the module reads the operations from a generated file:
|
|
635
430
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
431
|
+
```hcl
|
|
432
|
+
# packages/common/terraform/src/app/apis/my-api/my-api.tf
|
|
433
|
+
locals {
|
|
434
|
+
operations_file = "${path.module}/../../../generated/my-api/operations.json"
|
|
435
|
+
operations = fileexists(local.operations_file) ? jsondecode(file(local.operations_file)) : {}
|
|
640
436
|
}
|
|
641
437
|
```
|
|
438
|
+
|
|
439
|
+
This file is generated from your API, so you do not need to edit this by hand. Adding an operation to your API application code adds the route and lambda function on the next deploy. It is `.gitignore`d by default; remove the entry if you prefer to check it in.
|
|
642
440
|
</Fragment>
|
|
643
441
|
</Infrastructure>
|
|
442
|
+
|
|
443
|
+
<OptionFilter when={{ iac: 'terraform', infra: 'rest-lambda' }} description="Raising the REST API path depth limit in Terraform">
|
|
444
|
+
##### Terraform REST API Path Depth Limit
|
|
445
|
+
|
|
446
|
+
:::caution
|
|
447
|
+
Due to a limitation with Terraform where instances of resources can't reference one another (see [hashicorp/terraform#26697](https://github.com/hashicorp/terraform/issues/26697)), the API Gateway resource tree is built one level at a time rather than recursively, supporting operation paths of up to 16 segments. If an operation's path exceeds this, the plan fails with a message naming the paths that are too deep.
|
|
448
|
+
|
|
449
|
+
<Drawer title="Supporting deeper paths" trigger="Click here for instructions to support deeper paths should your API require it">
|
|
450
|
+
|
|
451
|
+
Edit `packages/common/terraform/src/app/apis/<my-api>/<my-api>.tf`:
|
|
452
|
+
|
|
453
|
+
<Steps>
|
|
454
|
+
1. Increment `max_path_depth` in `locals`:
|
|
455
|
+
|
|
456
|
+
```hcl
|
|
457
|
+
locals {
|
|
458
|
+
max_path_depth = 17
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
2. Copy the last `aws_api_gateway_resource` block, incrementing both the resource name and its parent:
|
|
463
|
+
|
|
464
|
+
```hcl
|
|
465
|
+
resource "aws_api_gateway_resource" "path_depth_16" {
|
|
466
|
+
for_each = local.path_nodes_by_depth[16]
|
|
467
|
+
|
|
468
|
+
rest_api_id = module.rest_api.api_id
|
|
469
|
+
parent_id = aws_api_gateway_resource.path_depth_15[each.value.parent].id
|
|
470
|
+
path_part = each.value.part
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
3. Add the new level to the `resource_ids` local:
|
|
475
|
+
|
|
476
|
+
```hcl
|
|
477
|
+
locals {
|
|
478
|
+
resource_ids = merge(
|
|
479
|
+
...
|
|
480
|
+
{ for path, resource in aws_api_gateway_resource.path_depth_16 : path => resource.id },
|
|
481
|
+
)
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
</Steps>
|
|
485
|
+
|
|
486
|
+
</Drawer>
|
|
487
|
+
:::
|
|
488
|
+
</OptionFilter>
|