@aws/nx-plugin 1.0.0-rc.83 → 1.0.0-rc.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/generators.json +7 -0
- package/migrations.json +31 -1
- package/package.json +1 -1
- package/src/agentcore-gateway/__snapshots__/generator.spec.ts.snap +51 -2
- package/src/agentcore-harness/__snapshots__/generator.spec.ts.snap +4 -5
- package/src/agentcore-harness/files/project/README.md.template +4 -5
- package/src/internal/test-matrix/generator.js +16 -0
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/__snapshots__/migration.spec.ts.snap +79 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/metadata.json +3 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/migration.d.ts +6 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/migration.js +87 -0
- package/src/migrations/latest/agentcore-harness-no-tools-by-default/migration.js.map +1 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/__snapshots__/migration.spec.ts.snap +54 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/metadata.json +3 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/migration.d.ts +6 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/migration.js +86 -0
- package/src/migrations/latest/rdb-terraform-aurora-app-module-defaults/migration.js.map +1 -0
- package/src/migrations/latest/terraform-declare-used-providers/metadata.json +3 -0
- package/src/migrations/latest/terraform-declare-used-providers/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-declare-used-providers/migration.js +147 -0
- package/src/migrations/latest/terraform-declare-used-providers/migration.js.map +1 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/__snapshots__/migration.spec.ts.snap +521 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/metadata.json +3 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration.js +504 -0
- package/src/migrations/latest/terraform-harness-vpc-role-and-memory-grant/migration.js.map +1 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/metadata.json +3 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.d.ts +6 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.js +146 -0
- package/src/migrations/latest/terraform-project-checkov-target-and-bootstrap-destroy/migration.js.map +1 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/__snapshots__/migration.spec.ts.snap +286 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/metadata.json +3 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/migration.d.ts +6 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/migration.js +238 -0
- package/src/migrations/latest/waf-log-group-cmk-encryption/migration.js.map +1 -0
- package/src/open-api/json-metadata/generator.d.ts +24 -0
- package/src/open-api/json-metadata/generator.js +37 -0
- package/src/open-api/json-metadata/generator.js.map +1 -0
- package/src/open-api/json-metadata/schema.d.js +6 -0
- package/src/open-api/json-metadata/schema.d.js.map +1 -0
- package/src/open-api/json-metadata/schema.d.ts +9 -0
- package/src/open-api/json-metadata/schema.json +20 -0
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +12 -0
- package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +1875 -623
- package/src/py/fast-api/generator.js +2 -1
- package/src/py/fast-api/generator.js.map +1 -1
- package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +8 -0
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +31 -2
- package/src/sdk/open-api.d.ts +2 -0
- package/src/sdk/open-api.js +2 -1
- package/src/sdk/open-api.js.map +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +1756 -457
- package/src/smithy/ts/api/generator.js +2 -1
- package/src/smithy/ts/api/generator.js.map +1 -1
- package/src/terraform/project/files/application/bootstrap/providers.tf.template +11 -0
- package/src/terraform/project/files/application/scripts/bootstrap-destroy.ts.template +111 -0
- package/src/terraform/project/files/application/src/providers.tf.template +6 -0
- package/src/terraform/project/files/checkov/checkov.yml.template +8 -0
- package/src/terraform/project/files/library/src/main.tf.template +9 -0
- package/src/terraform/project/generator.js +47 -4
- package/src/terraform/project/generator.js.map +1 -1
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +1848 -614
- package/src/trpc/backend/files-operations/scripts/generate-operations.ts.template +40 -0
- package/src/trpc/backend/generator.js +10 -0
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +8 -0
- package/src/ts/dcr-proxy/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +8 -0
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +62 -4
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +4 -0
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.spec.ts.snap +35 -8
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +4 -0
- package/src/utils/agent-core-constructs/files/cdk/app/agentcore-harness/__nameKebabCase__/__nameKebabCase__.ts.template +39 -1
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +8 -1
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +57 -2
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-harness/__nameKebabCase__/__nameKebabCase__.tf.template +258 -24
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +4 -0
- package/src/utils/api-constructs/api-constructs.js +11 -0
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +251 -3
- package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +437 -2
- package/src/utils/api-constructs/files/terraform/core/api/rest/rest-api/rest-api.tf.template +60 -7
- package/src/utils/api-constructs/open-api-metadata.d.ts +20 -3
- package/src/utils/api-constructs/open-api-metadata.js +64 -8
- package/src/utils/api-constructs/open-api-metadata.js.map +1 -1
- package/src/utils/api-constructs/trpc-operations-metadata.d.ts +21 -0
- package/src/utils/api-constructs/trpc-operations-metadata.js +55 -0
- package/src/utils/api-constructs/trpc-operations-metadata.js.map +1 -0
- package/src/utils/dcr-proxy-constructs/files/terraform/app/dcr-proxies/__nameKebabCase__/__nameKebabCase__.tf.template +4 -0
- package/src/utils/files/terraform/src/metrics/providers.tf.template +12 -0
- package/src/utils/function-constructs/files/terraform/app/lambda-functions/__nameKebabCase__/__nameKebabCase__.tf.template +4 -0
- package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +33 -8
- package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +4 -0
- package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +51 -2
- package/src/utils/rdb-constructs/files/cdk/core/rdb/aurora.ts.template +18 -0
- package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +15 -4
- package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +2 -2
- package/src/utils/rdb-constructs/rdb-constructs.d.ts +12 -0
- package/src/utils/rdb-constructs/rdb-constructs.js +24 -3
- package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
- package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +4 -0
|
@@ -2,10 +2,18 @@ terraform {
|
|
|
2
2
|
required_version = ">= 1.0"
|
|
3
3
|
|
|
4
4
|
required_providers {
|
|
5
|
+
archive = {
|
|
6
|
+
source = "hashicorp/archive"
|
|
7
|
+
version = "<%- archiveProviderVersion %>"
|
|
8
|
+
}
|
|
5
9
|
aws = {
|
|
6
10
|
source = "hashicorp/aws"
|
|
7
11
|
version = "<%- awsProviderVersion %>"
|
|
8
12
|
}
|
|
13
|
+
random = {
|
|
14
|
+
source = "hashicorp/random"
|
|
15
|
+
version = "<%- randomProviderVersion %>"
|
|
16
|
+
}
|
|
9
17
|
}
|
|
10
18
|
}
|
|
11
19
|
|
|
@@ -127,6 +135,51 @@ resource "random_string" "suffix" {
|
|
|
127
135
|
upper = false
|
|
128
136
|
}
|
|
129
137
|
|
|
138
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
139
|
+
locals {
|
|
140
|
+
# Generated at build time from the API definition
|
|
141
|
+
operations_file = "${path.module}/../../../generated/<%- apiNameKebabCase %>/operations.json"
|
|
142
|
+
operations = fileexists(local.operations_file) ? jsondecode(file(local.operations_file)) : {}
|
|
143
|
+
|
|
144
|
+
operation_slug = { for op in keys(local.operations) : op => replace(op, "/[^a-zA-Z0-9-_]/", "-") }
|
|
145
|
+
operation_hash = { for op in keys(local.operations) : op => substr(sha256(op), 0, 8) }
|
|
146
|
+
|
|
147
|
+
function_name = { for op in keys(local.operations) : op =>
|
|
148
|
+
"${substr("<%- apiNameClassName %>-${local.operation_slug[op]}", 0, 64 - length(local.operation_hash[op]) - length(random_string.suffix.result) - 2)}-${local.operation_hash[op]}-${random_string.suffix.result}"
|
|
149
|
+
}
|
|
150
|
+
role_name = { for op in keys(local.operations) : op =>
|
|
151
|
+
"${substr("<%- apiNameClassName %>-${local.operation_slug[op]}-role", 0, 64 - length(local.operation_hash[op]) - length(random_string.suffix.result) - 2)}-${local.operation_hash[op]}-${random_string.suffix.result}"
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
operation_path = { for op, details in local.operations : op =>
|
|
155
|
+
startswith(details.path, "/") ? details.path : "/${details.path}"
|
|
156
|
+
}
|
|
157
|
+
route_key = { for op, details in local.operations : op =>
|
|
158
|
+
"${upper(details.method)} ${local.operation_path[op]}"
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
permission_source_suffix = { for op, details in local.operations : op =>
|
|
162
|
+
"${upper(details.method)}${replace(local.operation_path[op], "/{[^}]*}/", "*")}"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
resource "terraform_data" "operations_metadata" {
|
|
167
|
+
# Fails the plan when the operations metadata has not been generated
|
|
168
|
+
input = local.operations_file
|
|
169
|
+
|
|
170
|
+
lifecycle {
|
|
171
|
+
precondition {
|
|
172
|
+
condition = fileexists(local.operations_file)
|
|
173
|
+
error_message = "Operations metadata not found at ${local.operations_file}. Build the <%- apiNameClassName %> project to generate it."
|
|
174
|
+
}
|
|
175
|
+
precondition {
|
|
176
|
+
condition = length(local.operations) > 0
|
|
177
|
+
error_message = "No operations found in ${local.operations_file}. The <%- apiNameClassName %> API must define at least one operation."
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
<%_ } _%>
|
|
182
|
+
|
|
130
183
|
# Resources
|
|
131
184
|
|
|
132
185
|
# Create Lambda ZIP file from the bundle directory
|
|
@@ -187,9 +240,14 @@ resource "aws_vpc_security_group_egress_rule" "api_lambda_https" {
|
|
|
187
240
|
description = "Allow outbound HTTPS to AWS service endpoints"
|
|
188
241
|
}
|
|
189
242
|
|
|
190
|
-
# Lambda function
|
|
191
|
-
# This configures a single "router" lambda to serve all requests
|
|
192
243
|
resource "aws_lambda_function" "api_lambda" {
|
|
244
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
245
|
+
# One lambda function per operation, each serving just that operation
|
|
246
|
+
for_each = local.operations
|
|
247
|
+
|
|
248
|
+
<%_ } else { _%>
|
|
249
|
+
# A single "router" lambda serving all requests
|
|
250
|
+
<%_ } _%>
|
|
193
251
|
#checkov:skip=CKV_AWS_117:Lambda function is optionally deployed into a VPC via vpc_id/subnet_ids; not required for this use case
|
|
194
252
|
#checkov:skip=CKV_AWS_116:Dead Letter Queue not required for this simple API use case
|
|
195
253
|
#checkov:skip=CKV_AWS_272:Code signing not required for this use case
|
|
@@ -198,8 +256,13 @@ resource "aws_lambda_function" "api_lambda" {
|
|
|
198
256
|
s3_bucket = aws_s3_object.lambda_zip.bucket
|
|
199
257
|
s3_key = aws_s3_object.lambda_zip.key
|
|
200
258
|
s3_object_version = aws_s3_object.lambda_zip.version_id
|
|
259
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
260
|
+
function_name = local.function_name[each.key]
|
|
261
|
+
role = aws_iam_role.lambda_execution_role[each.key].arn
|
|
262
|
+
<%_ } else { _%>
|
|
201
263
|
function_name = "<%- apiNameClassName %>Handler-${random_string.suffix.result}"
|
|
202
264
|
role = aws_iam_role.lambda_execution_role.arn
|
|
265
|
+
<%_ } _%>
|
|
203
266
|
<%_ if (['trpc', 'smithy'].includes(backend.type)) { _%>
|
|
204
267
|
handler = "index.handler"
|
|
205
268
|
runtime = "nodejs22.x"
|
|
@@ -255,7 +318,13 @@ resource "aws_lambda_function" "api_lambda" {
|
|
|
255
318
|
|
|
256
319
|
# IAM role for Lambda execution
|
|
257
320
|
resource "aws_iam_role" "lambda_execution_role" {
|
|
321
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
322
|
+
for_each = local.operations
|
|
323
|
+
|
|
324
|
+
name = local.role_name[each.key]
|
|
325
|
+
<%_ } else { _%>
|
|
258
326
|
name = "<%- apiNameClassName %>Handler-execution-role-${random_string.suffix.result}"
|
|
327
|
+
<%_ } _%>
|
|
259
328
|
|
|
260
329
|
assume_role_policy = jsonencode({
|
|
261
330
|
Version = "2012-10-17"
|
|
@@ -275,25 +344,57 @@ resource "aws_iam_role" "lambda_execution_role" {
|
|
|
275
344
|
|
|
276
345
|
# Attach basic execution policy to Lambda role
|
|
277
346
|
resource "aws_iam_role_policy_attachment" "lambda_basic_execution" {
|
|
347
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
348
|
+
for_each = local.operations
|
|
349
|
+
|
|
350
|
+
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
|
351
|
+
role = aws_iam_role.lambda_execution_role[each.key].name
|
|
352
|
+
<%_ } else { _%>
|
|
278
353
|
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
|
279
354
|
role = aws_iam_role.lambda_execution_role.name
|
|
355
|
+
<%_ } _%>
|
|
280
356
|
}
|
|
281
357
|
|
|
282
358
|
# Attach X-Ray tracing policy to Lambda role
|
|
283
359
|
resource "aws_iam_role_policy_attachment" "lambda_xray_execution" {
|
|
360
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
361
|
+
for_each = local.operations
|
|
362
|
+
|
|
363
|
+
policy_arn = "arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess"
|
|
364
|
+
role = aws_iam_role.lambda_execution_role[each.key].name
|
|
365
|
+
<%_ } else { _%>
|
|
284
366
|
policy_arn = "arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess"
|
|
285
367
|
role = aws_iam_role.lambda_execution_role.name
|
|
368
|
+
<%_ } _%>
|
|
286
369
|
}
|
|
287
370
|
|
|
288
371
|
# Attach VPC access policy to Lambda role when deployed into a VPC
|
|
289
372
|
resource "aws_iam_role_policy_attachment" "lambda_vpc_access" {
|
|
373
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
374
|
+
for_each = var.enable_vpc ? local.operations : {}
|
|
375
|
+
|
|
376
|
+
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
|
|
377
|
+
role = aws_iam_role.lambda_execution_role[each.key].name
|
|
378
|
+
<%_ } else { _%>
|
|
290
379
|
count = var.enable_vpc ? 1 : 0
|
|
291
380
|
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
|
|
292
381
|
role = aws_iam_role.lambda_execution_role.name
|
|
382
|
+
<%_ } _%>
|
|
293
383
|
}
|
|
294
384
|
|
|
295
385
|
# Additional IAM policies for Lambda (if provided)
|
|
296
386
|
resource "aws_iam_role_policy" "lambda_additional_policies" {
|
|
387
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
388
|
+
for_each = local.operations
|
|
389
|
+
|
|
390
|
+
name = "${substr(local.function_name[each.key], 0, 55)}-policies"
|
|
391
|
+
role = aws_iam_role.lambda_execution_role[each.key].id
|
|
392
|
+
|
|
393
|
+
policy = jsonencode({
|
|
394
|
+
Version = "2012-10-17"
|
|
395
|
+
Statement = local.lambda_policy_document_statements
|
|
396
|
+
})
|
|
397
|
+
<%_ } else { _%>
|
|
297
398
|
count = length(local.lambda_policy_statements) > 0 ? 1 : 0
|
|
298
399
|
name = "<%- apiNameClassName %>Handler-additional-policies-${random_string.suffix.result}"
|
|
299
400
|
role = aws_iam_role.lambda_execution_role.id
|
|
@@ -302,6 +403,7 @@ resource "aws_iam_role_policy" "lambda_additional_policies" {
|
|
|
302
403
|
Version = "2012-10-17"
|
|
303
404
|
Statement = local.lambda_policy_statements
|
|
304
405
|
})
|
|
406
|
+
<%_ } _%>
|
|
305
407
|
}
|
|
306
408
|
|
|
307
409
|
locals {
|
|
@@ -316,6 +418,17 @@ locals {
|
|
|
316
418
|
Resource = ["${var.appconfig_application_arn}/*"]
|
|
317
419
|
}
|
|
318
420
|
] : [], var.additional_iam_policy_statements)
|
|
421
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
422
|
+
|
|
423
|
+
# IAM rejects an empty statement list, so fall back to a no-op deny
|
|
424
|
+
lambda_policy_document_statements = length(local.lambda_policy_statements) > 0 ? local.lambda_policy_statements : [
|
|
425
|
+
{
|
|
426
|
+
Effect = "Deny"
|
|
427
|
+
Action = ["appconfig:GetLatestConfiguration"]
|
|
428
|
+
Resource = ["arn:aws:appconfig:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:application/none"]
|
|
429
|
+
}
|
|
430
|
+
]
|
|
431
|
+
<%_ } _%>
|
|
319
432
|
}
|
|
320
433
|
|
|
321
434
|
# CloudWatch Log Group for Lambda
|
|
@@ -323,16 +436,31 @@ resource "aws_cloudwatch_log_group" "lambda_logs" {
|
|
|
323
436
|
#checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
|
|
324
437
|
#checkov:skip=CKV_AWS_338:Log retention set to forever
|
|
325
438
|
#checkov:skip=CKV_AWS_66:Log retention set to forever
|
|
439
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
440
|
+
for_each = local.operations
|
|
441
|
+
|
|
442
|
+
name = "/aws/lambda/${local.function_name[each.key]}"
|
|
443
|
+
tags = var.tags
|
|
444
|
+
<%_ } else { _%>
|
|
326
445
|
name = "/aws/lambda/<%- apiNameClassName %>Handler-${random_string.suffix.result}"
|
|
327
446
|
tags = var.tags
|
|
447
|
+
<%_ } _%>
|
|
328
448
|
}
|
|
329
449
|
|
|
330
450
|
<%_ if (backend.type === 'fastapi') { _%>
|
|
331
451
|
# Lambda alias pointing to the latest published version for SnapStart
|
|
332
452
|
resource "aws_lambda_alias" "live" {
|
|
453
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
454
|
+
for_each = local.operations
|
|
455
|
+
|
|
456
|
+
name = "live"
|
|
457
|
+
function_name = aws_lambda_function.api_lambda[each.key].function_name
|
|
458
|
+
function_version = aws_lambda_function.api_lambda[each.key].version
|
|
459
|
+
<%_ } else { _%>
|
|
333
460
|
name = "live"
|
|
334
461
|
function_name = aws_lambda_function.api_lambda.function_name
|
|
335
462
|
function_version = aws_lambda_function.api_lambda.version
|
|
463
|
+
<%_ } _%>
|
|
336
464
|
|
|
337
465
|
depends_on = [aws_lambda_function.api_lambda]
|
|
338
466
|
}
|
|
@@ -447,7 +575,8 @@ resource "aws_apigatewayv2_authorizer" "custom_authorizer" {
|
|
|
447
575
|
authorizer_type = "REQUEST"
|
|
448
576
|
authorizer_uri = aws_lambda_function.authorizer_lambda.invoke_arn
|
|
449
577
|
authorizer_payload_format_version = "2.0"
|
|
450
|
-
authorizer_result_ttl_in_seconds =
|
|
578
|
+
authorizer_result_ttl_in_seconds = 300
|
|
579
|
+
identity_sources = ["$request.header.Authorization"]
|
|
451
580
|
enable_simple_responses = true
|
|
452
581
|
name = "<%- apiNameClassName %>Authorizer-${random_string.suffix.result}"
|
|
453
582
|
}
|
|
@@ -463,6 +592,17 @@ resource "aws_lambda_permission" "authorizer_invoke" {
|
|
|
463
592
|
|
|
464
593
|
# Lambda integration for HTTP API
|
|
465
594
|
resource "aws_apigatewayv2_integration" "lambda_integration" {
|
|
595
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
596
|
+
for_each = local.operations
|
|
597
|
+
|
|
598
|
+
api_id = module.http_api.api_id
|
|
599
|
+
integration_type = "AWS_PROXY"
|
|
600
|
+
<%_ if (backend.type === 'fastapi') { _%>
|
|
601
|
+
integration_uri = aws_lambda_alias.live[each.key].invoke_arn
|
|
602
|
+
<%_ } else { _%>
|
|
603
|
+
integration_uri = aws_lambda_function.api_lambda[each.key].invoke_arn
|
|
604
|
+
<%_ } _%>
|
|
605
|
+
<%_ } else { _%>
|
|
466
606
|
api_id = module.http_api.api_id
|
|
467
607
|
integration_type = "AWS_PROXY"
|
|
468
608
|
<%_ if (backend.type === 'fastapi') { _%>
|
|
@@ -470,6 +610,7 @@ resource "aws_apigatewayv2_integration" "lambda_integration" {
|
|
|
470
610
|
<%_ } else { _%>
|
|
471
611
|
integration_uri = aws_lambda_function.api_lambda.invoke_arn
|
|
472
612
|
<%_ } _%>
|
|
613
|
+
<%_ } _%>
|
|
473
614
|
|
|
474
615
|
payload_format_version = "2.0"
|
|
475
616
|
timeout_milliseconds = 30000
|
|
@@ -481,6 +622,28 @@ resource "aws_apigatewayv2_integration" "lambda_integration" {
|
|
|
481
622
|
<%_ } _%>
|
|
482
623
|
}
|
|
483
624
|
|
|
625
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
626
|
+
# One route per operation, each targeting that operation's integration
|
|
627
|
+
resource "aws_apigatewayv2_route" "operation_routes" {
|
|
628
|
+
for_each = local.operations
|
|
629
|
+
|
|
630
|
+
api_id = module.http_api.api_id
|
|
631
|
+
route_key = local.route_key[each.key]
|
|
632
|
+
target = "integrations/${aws_apigatewayv2_integration.lambda_integration[each.key].id}"
|
|
633
|
+
|
|
634
|
+
<%_ if (auth === 'iam') { _%>
|
|
635
|
+
authorization_type = "AWS_IAM"
|
|
636
|
+
<%_ } else if (auth === 'cognito') { _%>
|
|
637
|
+
authorization_type = "JWT"
|
|
638
|
+
authorizer_id = aws_apigatewayv2_authorizer.cognito_authorizer.id
|
|
639
|
+
<%_ } else if (auth === 'custom') { _%>
|
|
640
|
+
authorization_type = "CUSTOM"
|
|
641
|
+
authorizer_id = aws_apigatewayv2_authorizer.custom_authorizer.id
|
|
642
|
+
<%_ } _%>
|
|
643
|
+
|
|
644
|
+
depends_on = [aws_apigatewayv2_integration.lambda_integration<% if (auth === 'cognito') { %>, aws_apigatewayv2_authorizer.cognito_authorizer<% } else if (auth === 'custom') { %>, aws_apigatewayv2_authorizer.custom_authorizer<% } %>]
|
|
645
|
+
}
|
|
646
|
+
<%_ } else { _%>
|
|
484
647
|
# Route for proxy integration (catches all requests)
|
|
485
648
|
resource "aws_apigatewayv2_route" "proxy_routes" {
|
|
486
649
|
# NB: OPTIONS is omitted here since API Gateway manages responding to preflight requests
|
|
@@ -503,6 +666,7 @@ resource "aws_apigatewayv2_route" "proxy_routes" {
|
|
|
503
666
|
|
|
504
667
|
depends_on = [aws_apigatewayv2_integration.lambda_integration<% if (auth === 'cognito') { %>, aws_apigatewayv2_authorizer.cognito_authorizer<% } else if (auth === 'custom') { %>, aws_apigatewayv2_authorizer.custom_authorizer<% } %>]
|
|
505
668
|
}
|
|
669
|
+
<%_ } _%>
|
|
506
670
|
|
|
507
671
|
# Add API url to runtime config
|
|
508
672
|
module "add_url_to_runtime_config" {
|
|
@@ -517,6 +681,18 @@ module "add_url_to_runtime_config" {
|
|
|
517
681
|
|
|
518
682
|
# Lambda permission for API Gateway to invoke the function<% if (backend.type === 'fastapi') { %> via alias<% } %>
|
|
519
683
|
resource "aws_lambda_permission" "api_gateway_invoke" {
|
|
684
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
685
|
+
for_each = local.operations
|
|
686
|
+
|
|
687
|
+
statement_id = "AllowExecutionFromAPIGateway"
|
|
688
|
+
action = "lambda:InvokeFunction"
|
|
689
|
+
function_name = aws_lambda_function.api_lambda[each.key].function_name
|
|
690
|
+
<%_ if (backend.type === 'fastapi') { _%>
|
|
691
|
+
qualifier = aws_lambda_alias.live[each.key].name
|
|
692
|
+
<%_ } _%>
|
|
693
|
+
principal = "apigateway.amazonaws.com"
|
|
694
|
+
source_arn = "${module.http_api.api_execution_arn}/*/${local.permission_source_suffix[each.key]}"
|
|
695
|
+
<%_ } else { _%>
|
|
520
696
|
statement_id = "AllowExecutionFromAPIGateway"
|
|
521
697
|
action = "lambda:InvokeFunction"
|
|
522
698
|
function_name = aws_lambda_function.api_lambda.function_name
|
|
@@ -525,6 +701,7 @@ resource "aws_lambda_permission" "api_gateway_invoke" {
|
|
|
525
701
|
<%_ } _%>
|
|
526
702
|
principal = "apigateway.amazonaws.com"
|
|
527
703
|
source_arn = "${module.http_api.api_execution_arn}/*/*"
|
|
704
|
+
<%_ } _%>
|
|
528
705
|
|
|
529
706
|
<%_ if (backend.type === 'fastapi') { _%>
|
|
530
707
|
depends_on = [module.http_api, aws_lambda_alias.live]
|
|
@@ -571,6 +748,76 @@ output "stage_execution_arn" {
|
|
|
571
748
|
value = module.http_api.stage_execution_arn
|
|
572
749
|
}
|
|
573
750
|
|
|
751
|
+
<%_ if (backend.integrationPattern === 'isolated') { _%>
|
|
752
|
+
# Lambda Function Outputs, keyed by operation name
|
|
753
|
+
output "operations" {
|
|
754
|
+
description = "Names of the API operations, each with its own Lambda function"
|
|
755
|
+
value = keys(local.operations)
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
output "lambda_function_names" {
|
|
759
|
+
description = "Name of each operation's Lambda function, keyed by operation name"
|
|
760
|
+
value = { for op, fn in aws_lambda_function.api_lambda : op => fn.function_name }
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
output "lambda_function_arns" {
|
|
764
|
+
description = "ARN of each operation's Lambda function, keyed by operation name"
|
|
765
|
+
value = { for op, fn in aws_lambda_function.api_lambda : op => fn.arn }
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
output "lambda_invoke_arns" {
|
|
769
|
+
description = "Invoke ARN of each operation's Lambda function, keyed by operation name"
|
|
770
|
+
value = { for op, fn in aws_lambda_function.api_lambda : op => fn.invoke_arn }
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
output "lambda_qualified_arns" {
|
|
774
|
+
description = "Qualified ARN of each operation's Lambda function, keyed by operation name"
|
|
775
|
+
value = { for op, fn in aws_lambda_function.api_lambda : op => fn.qualified_arn }
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
output "lambda_versions" {
|
|
779
|
+
description = "Version of each operation's Lambda function, keyed by operation name"
|
|
780
|
+
value = { for op, fn in aws_lambda_function.api_lambda : op => fn.version }
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
output "lambda_source_code_hash" {
|
|
784
|
+
description = "Base64-encoded SHA256 hash of the Lambda deployment package, shared by every operation"
|
|
785
|
+
value = data.archive_file.lambda_zip.output_base64sha256
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
# IAM Role Outputs, keyed by operation name
|
|
789
|
+
output "lambda_execution_role_arns" {
|
|
790
|
+
description = "ARN of each operation's Lambda execution role, keyed by operation name"
|
|
791
|
+
value = { for op, role in aws_iam_role.lambda_execution_role : op => role.arn }
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
output "lambda_execution_role_names" {
|
|
795
|
+
description = "Name of each operation's Lambda execution role, keyed by operation name. Attach additional policies to a specific operation's role by name."
|
|
796
|
+
value = { for op, role in aws_iam_role.lambda_execution_role : op => role.name }
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
output "security_group_id" {
|
|
800
|
+
description = "Security group ID shared by the API Lambda functions, for use in ingress rules on resources they must reach (e.g. a database). Null unless enable_vpc is true."
|
|
801
|
+
value = var.enable_vpc ? aws_security_group.api_lambda[0].id : null
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
# Integration Outputs, keyed by operation name
|
|
805
|
+
output "integration_ids" {
|
|
806
|
+
description = "ID of each operation's Lambda integration, keyed by operation name"
|
|
807
|
+
value = { for op, i in aws_apigatewayv2_integration.lambda_integration : op => i.id }
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
# CloudWatch Log Groups, keyed by operation name
|
|
811
|
+
output "lambda_log_group_names" {
|
|
812
|
+
description = "Name of each operation's Lambda CloudWatch log group, keyed by operation name"
|
|
813
|
+
value = { for op, lg in aws_cloudwatch_log_group.lambda_logs : op => lg.name }
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
output "lambda_log_group_arns" {
|
|
817
|
+
description = "ARN of each operation's Lambda CloudWatch log group, keyed by operation name"
|
|
818
|
+
value = { for op, lg in aws_cloudwatch_log_group.lambda_logs : op => lg.arn }
|
|
819
|
+
}
|
|
820
|
+
<%_ } else { _%>
|
|
574
821
|
# Lambda Function Outputs
|
|
575
822
|
output "lambda_function_name" {
|
|
576
823
|
description = "Name of the Lambda function"
|
|
@@ -639,6 +886,7 @@ output "lambda_log_group_arn" {
|
|
|
639
886
|
description = "ARN of the Lambda CloudWatch log group"
|
|
640
887
|
value = aws_cloudwatch_log_group.lambda_logs.arn
|
|
641
888
|
}
|
|
889
|
+
<%_ } _%>
|
|
642
890
|
|
|
643
891
|
output "api_log_group_name" {
|
|
644
892
|
description = "Name of the API Gateway CloudWatch log group"
|