@aws/nx-plugin 1.0.3 → 1.0.5

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 (39) hide show
  1. package/LICENSE-THIRD-PARTY +7 -7
  2. package/migrations.json +10 -5
  3. package/package.json +4 -4
  4. package/src/infra/app/__snapshots__/generator.spec.ts.snap +3 -3
  5. package/src/license/dependency-check/collectors/npm-collector.d.ts +14 -0
  6. package/src/license/dependency-check/collectors/npm-collector.js +35 -1
  7. package/src/license/dependency-check/collectors/npm-collector.js.map +1 -1
  8. package/src/migrations/latest/api-custom-domain-runtime-config/metadata.json +3 -0
  9. package/src/migrations/latest/api-custom-domain-runtime-config/migration.js +362 -0
  10. package/src/migrations/latest/api-custom-domain-runtime-config/migration.js.map +1 -0
  11. package/src/migrations/v1.0.3/0001-terraform-init-target/migration.d.ts +6 -0
  12. package/src/migrations/v1.0.3/0001-terraform-init-target/migration.js.map +1 -0
  13. package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +3 -3
  14. package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +3 -3
  15. package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +1 -1
  16. package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +54 -6
  17. package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +378 -6
  18. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +3 -3
  19. package/src/py/rdb/__snapshots__/generator.spec.ts.snap +2 -2
  20. package/src/smithy/project/__snapshots__/generator.spec.ts.snap +16 -16
  21. package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +253 -5
  22. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +432 -12
  23. package/src/ts/agent/__snapshots__/generator.spec.ts.snap +2 -2
  24. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +1 -1
  25. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +1 -1
  26. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +13 -13
  27. package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +1 -1
  28. package/src/utils/api-constructs/files/cdk/core/api/http/http-api.ts.template +34 -4
  29. package/src/utils/api-constructs/files/cdk/core/api/rest/rest-api.ts.template +20 -2
  30. package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +63 -1
  31. package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +63 -1
  32. package/src/utils/docker.d.ts +1 -1
  33. package/src/utils/versions.d.ts +54 -54
  34. package/src/utils/versions.js +54 -54
  35. package/src/utils/versions.js.map +1 -1
  36. package/src/migrations/latest/terraform-init-target/migration.js.map +0 -1
  37. /package/src/migrations/latest/{terraform-init-target → api-custom-domain-runtime-config}/migration.d.ts +0 -0
  38. /package/src/migrations/{latest/terraform-init-target → v1.0.3/0001-terraform-init-target}/metadata.json +0 -0
  39. /package/src/migrations/{latest/terraform-init-target → v1.0.3/0001-terraform-init-target}/migration.js +0 -0
@@ -1224,10 +1224,12 @@ import {
1224
1224
  } from './utils.js';
1225
1225
  import { CfnOutput, Stack } from 'aws-cdk-lib';
1226
1226
  import {
1227
+ DomainMappingOptions,
1227
1228
  HttpApi as _HttpApi,
1228
1229
  HttpApiProps as _HttpApiProps,
1229
1230
  HttpMethod,
1230
1231
  HttpStage,
1232
+ IDomainName,
1231
1233
  LogGroupLogDestination,
1232
1234
  ThrottleSettings,
1233
1235
  } from 'aws-cdk-lib/aws-apigatewayv2';
@@ -1245,7 +1247,7 @@ import { suppressRules } from '../checkov.js';
1245
1247
  export interface HttpApiProps<
1246
1248
  TIntegrations extends ApiIntegrations<TOperation, HttpApiIntegration>,
1247
1249
  TOperation extends string,
1248
- > extends _HttpApiProps {
1250
+ > extends Omit<_HttpApiProps, 'defaultDomainMapping'> {
1249
1251
  /**
1250
1252
  * Unique name for the API, used in runtime configuration
1251
1253
  */
@@ -1264,6 +1266,12 @@ export interface HttpApiProps<
1264
1266
  * @default { rateLimit: 10000, burstLimit: 5000 }
1265
1267
  */
1266
1268
  readonly throttle?: ThrottleSettings;
1269
+ /**
1270
+ * Custom domain mapped to the API's default stage
1271
+ */
1272
+ readonly defaultDomainMapping?: DomainMappingOptions & {
1273
+ readonly domainName: IDomainName;
1274
+ };
1267
1275
  }
1268
1276
 
1269
1277
  /**
@@ -1287,6 +1295,9 @@ export class HttpApi<
1287
1295
  /** Default auto-deployed stage */
1288
1296
  public readonly defaultStage: HttpStage;
1289
1297
 
1298
+ /** The URL clients call: the custom domain's if one is mapped, otherwise the stage's */
1299
+ private readonly apiUrl: string;
1300
+
1290
1301
  /** Map of operation names to their API Gateway integrations */
1291
1302
  public readonly integrations: TIntegrations;
1292
1303
 
@@ -1298,6 +1309,7 @@ export class HttpApi<
1298
1309
  operations,
1299
1310
  integrations,
1300
1311
  throttle = { rateLimit: 10000, burstLimit: 5000 },
1312
+ defaultDomainMapping,
1301
1313
  ...props
1302
1314
  }: HttpApiProps<TIntegrations, TOperation>,
1303
1315
  ) {
@@ -1330,12 +1342,16 @@ export class HttpApi<
1330
1342
 
1331
1343
  this.defaultStage = new HttpStage(this, 'DefaultStage', {
1332
1344
  httpApi: this.api,
1345
+ domainMapping: defaultDomainMapping,
1333
1346
  autoDeploy: true,
1334
1347
  throttle,
1335
1348
  accessLogSettings: {
1336
1349
  destination: new LogGroupLogDestination(accessLogGroup),
1337
1350
  },
1338
1351
  });
1352
+ this.apiUrl = defaultDomainMapping
1353
+ ? this.defaultStage.domainUrl
1354
+ : this.defaultStage.url!;
1339
1355
 
1340
1356
  // Resolve the integration for a given operation.
1341
1357
  // If the operation has a dedicated integration, use it; otherwise fall back to $router.
@@ -1368,22 +1384,36 @@ export class HttpApi<
1368
1384
  );
1369
1385
 
1370
1386
  new CfnOutput(this, \`\${apiName}Url\`, {
1371
- value: this.defaultStage.url!,
1387
+ value: this.apiUrl,
1372
1388
  });
1373
1389
 
1374
1390
  // Register the API URL in runtime configuration for client discovery
1375
1391
  const rc = RuntimeConfig.ensure(this);
1376
1392
  rc.set('connection', 'apis', {
1377
1393
  ...rc.get('connection').apis,
1378
- [apiName]: this.defaultStage.url!,
1394
+ [apiName]: this.apiUrl,
1379
1395
  });
1396
+
1397
+ // Target for the custom domain's DNS record
1398
+ if (defaultDomainMapping) {
1399
+ new CfnOutput(this, \`\${apiName}DomainNameAlias\`, {
1400
+ value: defaultDomainMapping.domainName.regionalDomainName,
1401
+ description:
1402
+ 'Regional domain name to point a CNAME record at for the custom domain, with any DNS provider',
1403
+ });
1404
+ new CfnOutput(this, \`\${apiName}DomainNameAliasHostedZoneId\`, {
1405
+ value: defaultDomainMapping.domainName.regionalHostedZoneId,
1406
+ description:
1407
+ 'Hosted zone ID of the regional domain name, needed only for a Route 53 alias record',
1408
+ });
1409
+ }
1380
1410
  }
1381
1411
 
1382
1412
  /**
1383
1413
  * Return the API url
1384
1414
  */
1385
1415
  public get url() {
1386
- return this.defaultStage.url;
1416
+ return this.apiUrl;
1387
1417
  }
1388
1418
  }
1389
1419
  "
@@ -2122,7 +2152,7 @@ import {
2122
2152
  Stage,
2123
2153
  ThrottleSettings,
2124
2154
  } from 'aws-cdk-lib/aws-apigateway';
2125
- import { IAspect, RemovalPolicy, Stack } from 'aws-cdk-lib';
2155
+ import { CfnOutput, IAspect, RemovalPolicy, Stack } from 'aws-cdk-lib';
2126
2156
  import {
2127
2157
  CfnLoggingConfiguration,
2128
2158
  CfnWebACL,
@@ -2211,6 +2241,7 @@ export class RestApi<
2211
2241
  integrations,
2212
2242
  enableWaf = true,
2213
2243
  throttle = { rateLimit: 10000, burstLimit: 5000 },
2244
+ domainName,
2214
2245
  ...props
2215
2246
  }: RestApiProps<TIntegrations, TOperation>,
2216
2247
  ) {
@@ -2236,6 +2267,7 @@ export class RestApi<
2236
2267
  // Create the API Gateway REST API
2237
2268
  this.api = new _RestApi(this, 'Api', {
2238
2269
  ...props,
2270
+ domainName,
2239
2271
  deployOptions: {
2240
2272
  accessLogDestination: new LogGroupLogDestination(accessLogs),
2241
2273
  accessLogFormat: AccessLogFormat.jsonWithStandardFields(),
@@ -2377,8 +2409,24 @@ export class RestApi<
2377
2409
  const rc = RuntimeConfig.ensure(this);
2378
2410
  rc.set('connection', 'apis', {
2379
2411
  ...rc.get('connection').apis,
2380
- [apiName]: this.api.url!,
2412
+ [apiName]: domainName
2413
+ ? \`https://\${domainName.domainName}/\${domainName.basePath ? \`\${domainName.basePath}/\` : ''}\`
2414
+ : this.api.url!,
2381
2415
  });
2416
+
2417
+ // Target for the custom domain's DNS record
2418
+ if (domainName) {
2419
+ new CfnOutput(this, \`\${apiName}DomainNameAlias\`, {
2420
+ value: this.api.domainName!.domainNameAliasDomainName,
2421
+ description:
2422
+ 'Domain name of the API Gateway endpoint (regional or edge) to point a CNAME record at for the custom domain, with any DNS provider',
2423
+ });
2424
+ new CfnOutput(this, \`\${apiName}DomainNameAliasHostedZoneId\`, {
2425
+ value: this.api.domainName!.domainNameAliasHostedZoneId,
2426
+ description:
2427
+ 'Hosted zone ID of that domain name, needed only for a Route 53 alias record',
2428
+ });
2429
+ }
2382
2430
  }
2383
2431
 
2384
2432
  /**
@@ -3541,6 +3589,19 @@ variable "tags" {
3541
3589
  default = {}
3542
3590
  }
3543
3591
 
3592
+ # Custom domain configuration
3593
+ variable "custom_domain_name" {
3594
+ description = "Custom domain name for the API. Requires acm_certificate_arn."
3595
+ type = string
3596
+ default = null
3597
+ }
3598
+
3599
+ variable "acm_certificate_arn" {
3600
+ description = "ARN of an ACM certificate (in the API's region) for the custom domain name."
3601
+ type = string
3602
+ default = null
3603
+ }
3604
+
3544
3605
  # Get current AWS region and account ID
3545
3606
  data "aws_region" "current" {}
3546
3607
  data "aws_caller_identity" "current" {}
@@ -3783,6 +3844,10 @@ locals {
3783
3844
  ]
3784
3845
  }
3785
3846
 
3847
+ locals {
3848
+ api_url = var.custom_domain_name == null ? module.http_api.stage_invoke_url : "https://\${var.custom_domain_name}/"
3849
+ }
3850
+
3786
3851
  # CloudWatch Log Group for Lambda
3787
3852
  resource "aws_cloudwatch_log_group" "lambda_logs" {
3788
3853
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -3842,11 +3907,41 @@ module "add_url_to_runtime_config" {
3842
3907
 
3843
3908
  namespace = "connection"
3844
3909
  key = "apis"
3845
- value = { "TestApi" = module.http_api.stage_invoke_url }
3910
+ value = { "TestApi" = local.api_url }
3846
3911
 
3847
3912
  depends_on = [module.http_api]
3848
3913
  }
3849
3914
 
3915
+ # Custom domain for the API
3916
+ resource "aws_apigatewayv2_domain_name" "custom_domain" {
3917
+ count = var.custom_domain_name == null ? 0 : 1
3918
+
3919
+ domain_name = var.custom_domain_name
3920
+
3921
+ domain_name_configuration {
3922
+ certificate_arn = var.acm_certificate_arn
3923
+ endpoint_type = "REGIONAL"
3924
+ security_policy = "TLS_1_2"
3925
+ }
3926
+
3927
+ tags = var.tags
3928
+
3929
+ lifecycle {
3930
+ precondition {
3931
+ condition = var.acm_certificate_arn != null
3932
+ error_message = "acm_certificate_arn is required when custom_domain_name is set."
3933
+ }
3934
+ }
3935
+ }
3936
+
3937
+ resource "aws_apigatewayv2_api_mapping" "custom_domain" {
3938
+ count = var.custom_domain_name == null ? 0 : 1
3939
+
3940
+ api_id = module.http_api.api_id
3941
+ stage = module.http_api.stage_id
3942
+ domain_name = aws_apigatewayv2_domain_name.custom_domain[0].domain_name
3943
+ }
3944
+
3850
3945
  # Lambda permission for API Gateway to invoke the function
3851
3946
  resource "aws_lambda_permission" "api_gateway_invoke" {
3852
3947
  for_each = local.operations
@@ -3888,6 +3983,21 @@ output "stage_invoke_url" {
3888
3983
  value = module.http_api.stage_invoke_url
3889
3984
  }
3890
3985
 
3986
+ output "api_url" {
3987
+ description = "URL clients should call: the custom domain if configured, otherwise the stage invoke URL"
3988
+ value = local.api_url
3989
+ }
3990
+
3991
+ output "custom_domain_target_domain_name" {
3992
+ description = "Target domain name to point a DNS alias or CNAME record at for the custom domain"
3993
+ value = var.custom_domain_name == null ? null : aws_apigatewayv2_domain_name.custom_domain[0].domain_name_configuration[0].target_domain_name
3994
+ }
3995
+
3996
+ output "custom_domain_hosted_zone_id" {
3997
+ description = "Hosted zone ID to use for a Route 53 alias record for the custom domain"
3998
+ value = var.custom_domain_name == null ? null : aws_apigatewayv2_domain_name.custom_domain[0].domain_name_configuration[0].hosted_zone_id
3999
+ }
4000
+
3891
4001
  output "stage_arn" {
3892
4002
  description = "ARN of the API Gateway stage"
3893
4003
  value = module.http_api.stage_arn
@@ -4346,6 +4456,19 @@ variable "tags" {
4346
4456
  default = {}
4347
4457
  }
4348
4458
 
4459
+ # Custom domain configuration
4460
+ variable "custom_domain_name" {
4461
+ description = "Custom domain name for the API. Requires acm_certificate_arn."
4462
+ type = string
4463
+ default = null
4464
+ }
4465
+
4466
+ variable "acm_certificate_arn" {
4467
+ description = "ARN of an ACM certificate (in the API's region) for the custom domain name."
4468
+ type = string
4469
+ default = null
4470
+ }
4471
+
4349
4472
  # Get current AWS region and account ID
4350
4473
  data "aws_region" "current" {}
4351
4474
  data "aws_caller_identity" "current" {}
@@ -4588,6 +4711,10 @@ locals {
4588
4711
  ]
4589
4712
  }
4590
4713
 
4714
+ locals {
4715
+ api_url = var.custom_domain_name == null ? module.http_api.stage_invoke_url : "https://\${var.custom_domain_name}/"
4716
+ }
4717
+
4591
4718
  # CloudWatch Log Group for Lambda
4592
4719
  resource "aws_cloudwatch_log_group" "lambda_logs" {
4593
4720
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -4730,11 +4857,41 @@ module "add_url_to_runtime_config" {
4730
4857
 
4731
4858
  namespace = "connection"
4732
4859
  key = "apis"
4733
- value = { "TestApi" = module.http_api.stage_invoke_url }
4860
+ value = { "TestApi" = local.api_url }
4734
4861
 
4735
4862
  depends_on = [module.http_api]
4736
4863
  }
4737
4864
 
4865
+ # Custom domain for the API
4866
+ resource "aws_apigatewayv2_domain_name" "custom_domain" {
4867
+ count = var.custom_domain_name == null ? 0 : 1
4868
+
4869
+ domain_name = var.custom_domain_name
4870
+
4871
+ domain_name_configuration {
4872
+ certificate_arn = var.acm_certificate_arn
4873
+ endpoint_type = "REGIONAL"
4874
+ security_policy = "TLS_1_2"
4875
+ }
4876
+
4877
+ tags = var.tags
4878
+
4879
+ lifecycle {
4880
+ precondition {
4881
+ condition = var.acm_certificate_arn != null
4882
+ error_message = "acm_certificate_arn is required when custom_domain_name is set."
4883
+ }
4884
+ }
4885
+ }
4886
+
4887
+ resource "aws_apigatewayv2_api_mapping" "custom_domain" {
4888
+ count = var.custom_domain_name == null ? 0 : 1
4889
+
4890
+ api_id = module.http_api.api_id
4891
+ stage = module.http_api.stage_id
4892
+ domain_name = aws_apigatewayv2_domain_name.custom_domain[0].domain_name
4893
+ }
4894
+
4738
4895
  # Lambda permission for API Gateway to invoke the function
4739
4896
  resource "aws_lambda_permission" "api_gateway_invoke" {
4740
4897
  for_each = local.operations
@@ -4776,6 +4933,21 @@ output "stage_invoke_url" {
4776
4933
  value = module.http_api.stage_invoke_url
4777
4934
  }
4778
4935
 
4936
+ output "api_url" {
4937
+ description = "URL clients should call: the custom domain if configured, otherwise the stage invoke URL"
4938
+ value = local.api_url
4939
+ }
4940
+
4941
+ output "custom_domain_target_domain_name" {
4942
+ description = "Target domain name to point a DNS alias or CNAME record at for the custom domain"
4943
+ value = var.custom_domain_name == null ? null : aws_apigatewayv2_domain_name.custom_domain[0].domain_name_configuration[0].target_domain_name
4944
+ }
4945
+
4946
+ output "custom_domain_hosted_zone_id" {
4947
+ description = "Hosted zone ID to use for a Route 53 alias record for the custom domain"
4948
+ value = var.custom_domain_name == null ? null : aws_apigatewayv2_domain_name.custom_domain[0].domain_name_configuration[0].hosted_zone_id
4949
+ }
4950
+
4779
4951
  output "stage_arn" {
4780
4952
  description = "ARN of the API Gateway stage"
4781
4953
  value = module.http_api.stage_arn
@@ -5234,6 +5406,19 @@ variable "tags" {
5234
5406
  default = {}
5235
5407
  }
5236
5408
 
5409
+ # Custom domain configuration
5410
+ variable "custom_domain_name" {
5411
+ description = "Custom domain name for the API. Requires acm_certificate_arn."
5412
+ type = string
5413
+ default = null
5414
+ }
5415
+
5416
+ variable "acm_certificate_arn" {
5417
+ description = "ARN of an ACM certificate (in the API's region) for the custom domain name."
5418
+ type = string
5419
+ default = null
5420
+ }
5421
+
5237
5422
  # Get current AWS region and account ID
5238
5423
  data "aws_region" "current" {}
5239
5424
  data "aws_caller_identity" "current" {}
@@ -5476,6 +5661,10 @@ locals {
5476
5661
  ]
5477
5662
  }
5478
5663
 
5664
+ locals {
5665
+ api_url = var.custom_domain_name == null ? module.http_api.stage_invoke_url : "https://\${var.custom_domain_name}/"
5666
+ }
5667
+
5479
5668
  # CloudWatch Log Group for Lambda
5480
5669
  resource "aws_cloudwatch_log_group" "lambda_logs" {
5481
5670
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -5522,11 +5711,41 @@ module "add_url_to_runtime_config" {
5522
5711
 
5523
5712
  namespace = "connection"
5524
5713
  key = "apis"
5525
- value = { "TestApi" = module.http_api.stage_invoke_url }
5714
+ value = { "TestApi" = local.api_url }
5526
5715
 
5527
5716
  depends_on = [module.http_api]
5528
5717
  }
5529
5718
 
5719
+ # Custom domain for the API
5720
+ resource "aws_apigatewayv2_domain_name" "custom_domain" {
5721
+ count = var.custom_domain_name == null ? 0 : 1
5722
+
5723
+ domain_name = var.custom_domain_name
5724
+
5725
+ domain_name_configuration {
5726
+ certificate_arn = var.acm_certificate_arn
5727
+ endpoint_type = "REGIONAL"
5728
+ security_policy = "TLS_1_2"
5729
+ }
5730
+
5731
+ tags = var.tags
5732
+
5733
+ lifecycle {
5734
+ precondition {
5735
+ condition = var.acm_certificate_arn != null
5736
+ error_message = "acm_certificate_arn is required when custom_domain_name is set."
5737
+ }
5738
+ }
5739
+ }
5740
+
5741
+ resource "aws_apigatewayv2_api_mapping" "custom_domain" {
5742
+ count = var.custom_domain_name == null ? 0 : 1
5743
+
5744
+ api_id = module.http_api.api_id
5745
+ stage = module.http_api.stage_id
5746
+ domain_name = aws_apigatewayv2_domain_name.custom_domain[0].domain_name
5747
+ }
5748
+
5530
5749
  # Lambda permission for API Gateway to invoke the function
5531
5750
  resource "aws_lambda_permission" "api_gateway_invoke" {
5532
5751
  for_each = local.operations
@@ -5568,6 +5787,21 @@ output "stage_invoke_url" {
5568
5787
  value = module.http_api.stage_invoke_url
5569
5788
  }
5570
5789
 
5790
+ output "api_url" {
5791
+ description = "URL clients should call: the custom domain if configured, otherwise the stage invoke URL"
5792
+ value = local.api_url
5793
+ }
5794
+
5795
+ output "custom_domain_target_domain_name" {
5796
+ description = "Target domain name to point a DNS alias or CNAME record at for the custom domain"
5797
+ value = var.custom_domain_name == null ? null : aws_apigatewayv2_domain_name.custom_domain[0].domain_name_configuration[0].target_domain_name
5798
+ }
5799
+
5800
+ output "custom_domain_hosted_zone_id" {
5801
+ description = "Hosted zone ID to use for a Route 53 alias record for the custom domain"
5802
+ value = var.custom_domain_name == null ? null : aws_apigatewayv2_domain_name.custom_domain[0].domain_name_configuration[0].hosted_zone_id
5803
+ }
5804
+
5571
5805
  output "stage_arn" {
5572
5806
  description = "ARN of the API Gateway stage"
5573
5807
  value = module.http_api.stage_arn
@@ -6094,6 +6328,19 @@ variable "tags" {
6094
6328
  default = {}
6095
6329
  }
6096
6330
 
6331
+ # Custom domain configuration
6332
+ variable "custom_domain_name" {
6333
+ description = "Custom domain name for the API. Requires acm_certificate_arn."
6334
+ type = string
6335
+ default = null
6336
+ }
6337
+
6338
+ variable "acm_certificate_arn" {
6339
+ description = "ARN of an ACM certificate (in the API's region) for the custom domain name."
6340
+ type = string
6341
+ default = null
6342
+ }
6343
+
6097
6344
  # Get current AWS region and account ID
6098
6345
  data "aws_region" "current" {}
6099
6346
  data "aws_caller_identity" "current" {}
@@ -6536,6 +6783,10 @@ locals {
6536
6783
  ]
6537
6784
  }
6538
6785
 
6786
+ locals {
6787
+ api_url = var.custom_domain_name == null ? "\${aws_api_gateway_stage.api_stage.invoke_url}/" : "https://\${var.custom_domain_name}/"
6788
+ }
6789
+
6539
6790
  # CloudWatch Log Group for Lambda
6540
6791
  resource "aws_cloudwatch_log_group" "lambda_logs" {
6541
6792
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -6838,11 +7089,41 @@ module "add_url_to_runtime_config" {
6838
7089
 
6839
7090
  namespace = "connection"
6840
7091
  key = "apis"
6841
- value = { "TestApi" = "\${aws_api_gateway_stage.api_stage.invoke_url}/" }
7092
+ value = { "TestApi" = local.api_url }
6842
7093
 
6843
7094
  depends_on = [aws_api_gateway_stage.api_stage]
6844
7095
  }
6845
7096
 
7097
+ # Custom domain for the API, served without the stage path prefix
7098
+ resource "aws_api_gateway_domain_name" "custom_domain" {
7099
+ count = var.custom_domain_name == null ? 0 : 1
7100
+
7101
+ domain_name = var.custom_domain_name
7102
+ regional_certificate_arn = var.acm_certificate_arn
7103
+ security_policy = "TLS_1_2"
7104
+
7105
+ endpoint_configuration {
7106
+ types = ["REGIONAL"]
7107
+ }
7108
+
7109
+ tags = var.tags
7110
+
7111
+ lifecycle {
7112
+ precondition {
7113
+ condition = var.acm_certificate_arn != null
7114
+ error_message = "acm_certificate_arn is required when custom_domain_name is set."
7115
+ }
7116
+ }
7117
+ }
7118
+
7119
+ resource "aws_api_gateway_base_path_mapping" "custom_domain" {
7120
+ count = var.custom_domain_name == null ? 0 : 1
7121
+
7122
+ api_id = module.rest_api.api_id
7123
+ stage_name = aws_api_gateway_stage.api_stage.stage_name
7124
+ domain_name = aws_api_gateway_domain_name.custom_domain[0].domain_name
7125
+ }
7126
+
6846
7127
  # Outputs
6847
7128
 
6848
7129
  # API Gateway Outputs (from core module)
@@ -6871,6 +7152,21 @@ output "stage_invoke_url" {
6871
7152
  value = aws_api_gateway_stage.api_stage.invoke_url
6872
7153
  }
6873
7154
 
7155
+ output "api_url" {
7156
+ description = "URL clients should call: the custom domain if configured, otherwise the stage invoke URL"
7157
+ value = local.api_url
7158
+ }
7159
+
7160
+ output "custom_domain_target_domain_name" {
7161
+ description = "Target domain name to point a DNS alias or CNAME record at for the custom domain"
7162
+ value = var.custom_domain_name == null ? null : aws_api_gateway_domain_name.custom_domain[0].regional_domain_name
7163
+ }
7164
+
7165
+ output "custom_domain_hosted_zone_id" {
7166
+ description = "Hosted zone ID to use for a Route 53 alias record for the custom domain"
7167
+ value = var.custom_domain_name == null ? null : aws_api_gateway_domain_name.custom_domain[0].regional_zone_id
7168
+ }
7169
+
6874
7170
  output "stage_arn" {
6875
7171
  description = "ARN of the API Gateway stage"
6876
7172
  value = aws_api_gateway_stage.api_stage.arn
@@ -7398,6 +7694,19 @@ variable "tags" {
7398
7694
  default = {}
7399
7695
  }
7400
7696
 
7697
+ # Custom domain configuration
7698
+ variable "custom_domain_name" {
7699
+ description = "Custom domain name for the API. Requires acm_certificate_arn."
7700
+ type = string
7701
+ default = null
7702
+ }
7703
+
7704
+ variable "acm_certificate_arn" {
7705
+ description = "ARN of an ACM certificate (in the API's region) for the custom domain name."
7706
+ type = string
7707
+ default = null
7708
+ }
7709
+
7401
7710
  # Get current AWS region and account ID
7402
7711
  data "aws_region" "current" {}
7403
7712
  data "aws_caller_identity" "current" {}
@@ -7840,6 +8149,10 @@ locals {
7840
8149
  ]
7841
8150
  }
7842
8151
 
8152
+ locals {
8153
+ api_url = var.custom_domain_name == null ? "\${aws_api_gateway_stage.api_stage.invoke_url}/" : "https://\${var.custom_domain_name}/"
8154
+ }
8155
+
7843
8156
  # CloudWatch Log Group for Lambda
7844
8157
  resource "aws_cloudwatch_log_group" "lambda_logs" {
7845
8158
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -8141,11 +8454,41 @@ module "add_url_to_runtime_config" {
8141
8454
 
8142
8455
  namespace = "connection"
8143
8456
  key = "apis"
8144
- value = { "TestApi" = "\${aws_api_gateway_stage.api_stage.invoke_url}/" }
8457
+ value = { "TestApi" = local.api_url }
8145
8458
 
8146
8459
  depends_on = [aws_api_gateway_stage.api_stage]
8147
8460
  }
8148
8461
 
8462
+ # Custom domain for the API, served without the stage path prefix
8463
+ resource "aws_api_gateway_domain_name" "custom_domain" {
8464
+ count = var.custom_domain_name == null ? 0 : 1
8465
+
8466
+ domain_name = var.custom_domain_name
8467
+ regional_certificate_arn = var.acm_certificate_arn
8468
+ security_policy = "TLS_1_2"
8469
+
8470
+ endpoint_configuration {
8471
+ types = ["REGIONAL"]
8472
+ }
8473
+
8474
+ tags = var.tags
8475
+
8476
+ lifecycle {
8477
+ precondition {
8478
+ condition = var.acm_certificate_arn != null
8479
+ error_message = "acm_certificate_arn is required when custom_domain_name is set."
8480
+ }
8481
+ }
8482
+ }
8483
+
8484
+ resource "aws_api_gateway_base_path_mapping" "custom_domain" {
8485
+ count = var.custom_domain_name == null ? 0 : 1
8486
+
8487
+ api_id = module.rest_api.api_id
8488
+ stage_name = aws_api_gateway_stage.api_stage.stage_name
8489
+ domain_name = aws_api_gateway_domain_name.custom_domain[0].domain_name
8490
+ }
8491
+
8149
8492
  # Outputs
8150
8493
 
8151
8494
  # API Gateway Outputs (from core module)
@@ -8174,6 +8517,21 @@ output "stage_invoke_url" {
8174
8517
  value = aws_api_gateway_stage.api_stage.invoke_url
8175
8518
  }
8176
8519
 
8520
+ output "api_url" {
8521
+ description = "URL clients should call: the custom domain if configured, otherwise the stage invoke URL"
8522
+ value = local.api_url
8523
+ }
8524
+
8525
+ output "custom_domain_target_domain_name" {
8526
+ description = "Target domain name to point a DNS alias or CNAME record at for the custom domain"
8527
+ value = var.custom_domain_name == null ? null : aws_api_gateway_domain_name.custom_domain[0].regional_domain_name
8528
+ }
8529
+
8530
+ output "custom_domain_hosted_zone_id" {
8531
+ description = "Hosted zone ID to use for a Route 53 alias record for the custom domain"
8532
+ value = var.custom_domain_name == null ? null : aws_api_gateway_domain_name.custom_domain[0].regional_zone_id
8533
+ }
8534
+
8177
8535
  output "stage_arn" {
8178
8536
  description = "ARN of the API Gateway stage"
8179
8537
  value = aws_api_gateway_stage.api_stage.arn
@@ -8701,6 +9059,19 @@ variable "tags" {
8701
9059
  default = {}
8702
9060
  }
8703
9061
 
9062
+ # Custom domain configuration
9063
+ variable "custom_domain_name" {
9064
+ description = "Custom domain name for the API. Requires acm_certificate_arn."
9065
+ type = string
9066
+ default = null
9067
+ }
9068
+
9069
+ variable "acm_certificate_arn" {
9070
+ description = "ARN of an ACM certificate (in the API's region) for the custom domain name."
9071
+ type = string
9072
+ default = null
9073
+ }
9074
+
8704
9075
  # Get current AWS region and account ID
8705
9076
  data "aws_region" "current" {}
8706
9077
  data "aws_caller_identity" "current" {}
@@ -9143,6 +9514,10 @@ locals {
9143
9514
  ]
9144
9515
  }
9145
9516
 
9517
+ locals {
9518
+ api_url = var.custom_domain_name == null ? "\${aws_api_gateway_stage.api_stage.invoke_url}/" : "https://\${var.custom_domain_name}/"
9519
+ }
9520
+
9146
9521
  # CloudWatch Log Group for Lambda
9147
9522
  resource "aws_cloudwatch_log_group" "lambda_logs" {
9148
9523
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -9527,11 +9902,41 @@ module "add_url_to_runtime_config" {
9527
9902
 
9528
9903
  namespace = "connection"
9529
9904
  key = "apis"
9530
- value = { "TestApi" = "\${aws_api_gateway_stage.api_stage.invoke_url}/" }
9905
+ value = { "TestApi" = local.api_url }
9531
9906
 
9532
9907
  depends_on = [aws_api_gateway_stage.api_stage]
9533
9908
  }
9534
9909
 
9910
+ # Custom domain for the API, served without the stage path prefix
9911
+ resource "aws_api_gateway_domain_name" "custom_domain" {
9912
+ count = var.custom_domain_name == null ? 0 : 1
9913
+
9914
+ domain_name = var.custom_domain_name
9915
+ regional_certificate_arn = var.acm_certificate_arn
9916
+ security_policy = "TLS_1_2"
9917
+
9918
+ endpoint_configuration {
9919
+ types = ["REGIONAL"]
9920
+ }
9921
+
9922
+ tags = var.tags
9923
+
9924
+ lifecycle {
9925
+ precondition {
9926
+ condition = var.acm_certificate_arn != null
9927
+ error_message = "acm_certificate_arn is required when custom_domain_name is set."
9928
+ }
9929
+ }
9930
+ }
9931
+
9932
+ resource "aws_api_gateway_base_path_mapping" "custom_domain" {
9933
+ count = var.custom_domain_name == null ? 0 : 1
9934
+
9935
+ api_id = module.rest_api.api_id
9936
+ stage_name = aws_api_gateway_stage.api_stage.stage_name
9937
+ domain_name = aws_api_gateway_domain_name.custom_domain[0].domain_name
9938
+ }
9939
+
9535
9940
  # Outputs
9536
9941
 
9537
9942
  # API Gateway Outputs (from core module)
@@ -9560,6 +9965,21 @@ output "stage_invoke_url" {
9560
9965
  value = aws_api_gateway_stage.api_stage.invoke_url
9561
9966
  }
9562
9967
 
9968
+ output "api_url" {
9969
+ description = "URL clients should call: the custom domain if configured, otherwise the stage invoke URL"
9970
+ value = local.api_url
9971
+ }
9972
+
9973
+ output "custom_domain_target_domain_name" {
9974
+ description = "Target domain name to point a DNS alias or CNAME record at for the custom domain"
9975
+ value = var.custom_domain_name == null ? null : aws_api_gateway_domain_name.custom_domain[0].regional_domain_name
9976
+ }
9977
+
9978
+ output "custom_domain_hosted_zone_id" {
9979
+ description = "Hosted zone ID to use for a Route 53 alias record for the custom domain"
9980
+ value = var.custom_domain_name == null ? null : aws_api_gateway_domain_name.custom_domain[0].regional_zone_id
9981
+ }
9982
+
9563
9983
  output "stage_arn" {
9564
9984
  description = "ARN of the API Gateway stage"
9565
9985
  value = aws_api_gateway_stage.api_stage.arn