@certenza/aws-cdk-infrastructure-commons 1.1.1 → 1.1.3

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.
@@ -67,38 +67,71 @@ const createApiGateway = (scope, apiName, domainName, hostedZoneId, zoneName) =>
67
67
  const hostedZone = (0, route53_1.getHostedZone)(scope, "HostedZone", hostedZoneId, zoneName);
68
68
  // Create a certificate for the API Gateway domain
69
69
  const certificate = (0, acm_1.createCertificate)(scope, `ApiGatewayCertificate`, domainName, hostedZone);
70
+ // Create access log group
71
+ const accessLogGroup = new logs.LogGroup(scope, `${apiName}-AccessLogs`, {
72
+ retention: logs.RetentionDays.ONE_WEEK,
73
+ });
74
+ // Create RestApi without auto-deployment so we can control the order of resource creation
70
75
  const api = new apigateway.RestApi(scope, apiName, {
71
76
  description: `Public API Gateway for ${apiName}`,
72
77
  endpointTypes: [apigateway.EndpointType.REGIONAL],
73
- domainName: {
74
- domainName: domainName,
75
- certificate: certificate,
76
- securityPolicy: apigateway.SecurityPolicy.TLS_1_2,
77
- endpointType: apigateway.EndpointType.REGIONAL,
78
- },
79
- deployOptions: {
80
- loggingLevel: apigateway.MethodLoggingLevel.INFO,
81
- dataTraceEnabled: false,
82
- accessLogDestination: new apigateway.LogGroupLogDestination(new logs.LogGroup(scope, `${apiName}-AccessLogs`, {
83
- retention: logs.RetentionDays.ONE_WEEK,
84
- })),
85
- },
78
+ deploy: false, // Don't auto-deploy - we'll create deployment and stage manually
86
79
  });
87
- // Set retention for execution log group that API Gateway creates automatically
80
+ // Create execution log group with the exact name API Gateway expects
88
81
  // API Gateway creates execution logs in the format: API-Gateway-Execution-Logs_{api-id}/{stage-name}
89
- // We use LogRetention to set the retention policy after API Gateway creates the log group
90
- new logs.LogRetention(scope, `${apiName}-ExecutionLogRetention`, {
82
+ // By creating it first, API Gateway will use our log group instead of creating a new one
83
+ // Note: The log group name depends on api.restApiId (a token), so CloudFormation will
84
+ // create the API first to resolve the token, then create the log group with the resolved name
85
+ const executionLogGroup = new logs.LogGroup(scope, `${apiName}-ExecutionLogs`, {
91
86
  logGroupName: cdk.Token.asString(cdk.Fn.join("/", [
92
- cdk.Fn.join("_", ["API-Gateway-Execution-Logs", api.restApiId]),
93
- api.deploymentStage.stageName,
87
+ cdk.Fn.join("_", [
88
+ "API-Gateway-Execution-Logs",
89
+ api.restApiId,
90
+ ]),
91
+ "prod", // Default stage name
94
92
  ])),
95
93
  retention: logs.RetentionDays.ONE_MONTH, // Budget-friendly: 1 month retention
94
+ removalPolicy: cdk.RemovalPolicy.DESTROY, // Destroy log group when API is deleted
95
+ });
96
+ // Create deployment
97
+ const deployment = new apigateway.Deployment(scope, `${apiName}-Deployment`, {
98
+ api: api,
99
+ });
100
+ // Create stage with logging configuration
101
+ // The execution log group must exist before the stage is created so API Gateway uses it
102
+ const stage = new apigateway.Stage(scope, `${apiName}-Stage`, {
103
+ deployment: deployment,
104
+ stageName: "prod",
105
+ loggingLevel: apigateway.MethodLoggingLevel.INFO,
106
+ dataTraceEnabled: false,
107
+ accessLogDestination: new apigateway.LogGroupLogDestination(accessLogGroup),
108
+ });
109
+ // Ensure the execution log group is created before the stage
110
+ // This is necessary because the stage doesn't reference the log group directly,
111
+ // but API Gateway needs it to exist when the stage is created
112
+ stage.node.addDependency(executionLogGroup);
113
+ // Create custom domain name with TLS 1.2 security policy
114
+ // CDK automatically ensures the certificate is validated before creating the domain
115
+ const apiDomain = new apigateway.DomainName(scope, `${apiName}-Domain`, {
116
+ domainName: domainName,
117
+ certificate: certificate,
118
+ securityPolicy: apigateway.SecurityPolicy.TLS_1_2, // Enforce TLS 1.2 minimum
119
+ endpointType: apigateway.EndpointType.REGIONAL,
120
+ });
121
+ // Map the custom domain to the API stage
122
+ // CDK automatically handles dependencies: BasePathMapping depends on apiDomain, api, and stage
123
+ new apigateway.BasePathMapping(scope, `${apiName}-BasePathMapping`, {
124
+ domainName: apiDomain,
125
+ restApi: api,
126
+ stage: stage,
96
127
  });
97
- // Create Route53 A record pointing to the API Gateway
128
+ // Create Route53 A record pointing to the API Gateway custom domain
129
+ // CDK automatically handles dependency: Route53 record waits for domain to be created
130
+ // via the alias target (ApiGatewayDomain)
98
131
  new route53.ARecord(scope, `${apiName}-AliasRecord`, {
99
132
  zone: hostedZone,
100
133
  recordName: domainName.replace(`${hostedZone.zoneName}.`, ""),
101
- target: route53.RecordTarget.fromAlias(new route53targets.ApiGateway(api)),
134
+ target: route53.RecordTarget.fromAlias(new route53targets.ApiGatewayDomain(apiDomain)),
102
135
  });
103
136
  // Return the API Gateway
104
137
  return api;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@certenza/aws-cdk-infrastructure-commons",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "Common infrastructure reusable utilities and resources for Certenza projects",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",