@gradientedge/cdk-utils-aws 2.3.0 → 2.4.1
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/dist/src/common/construct.d.ts +38 -0
- package/dist/src/common/construct.js +38 -0
- package/dist/src/common/resource-name-formatter.d.ts +12 -1
- package/dist/src/common/resource-name-formatter.js +12 -1
- package/dist/src/common/stack.d.ts +9 -0
- package/dist/src/common/stack.js +9 -0
- package/dist/src/common/types.d.ts +22 -0
- package/dist/src/construct/api-to-any-target/main.d.ts +19 -0
- package/dist/src/construct/api-to-any-target/main.js +19 -0
- package/dist/src/construct/api-to-eventbridge-target/main.d.ts +6 -0
- package/dist/src/construct/api-to-eventbridge-target/main.js +6 -0
- package/dist/src/construct/api-to-eventbridge-target-with-sns/main.d.ts +3 -0
- package/dist/src/construct/api-to-eventbridge-target-with-sns/main.js +3 -0
- package/dist/src/construct/api-to-lambda-target/main.d.ts +9 -0
- package/dist/src/construct/api-to-lambda-target/main.js +9 -0
- package/dist/src/construct/application-configuration/main.d.ts +27 -0
- package/dist/src/construct/application-configuration/main.js +27 -0
- package/dist/src/construct/event-handler/main.d.ts +3 -0
- package/dist/src/construct/event-handler/main.js +12 -1
- package/dist/src/construct/lambda-with-iam-access/main.d.ts +15 -0
- package/dist/src/construct/lambda-with-iam-access/main.js +22 -0
- package/dist/src/construct/piped-event-handler/main.d.ts +3 -0
- package/dist/src/construct/piped-event-handler/main.js +3 -0
- package/dist/src/construct/rest-api-lambda/main.js +3 -0
- package/dist/src/construct/rest-api-lambda-with-cache/main.d.ts +3 -0
- package/dist/src/construct/rest-api-lambda-with-cache/main.js +3 -0
- package/dist/src/construct/site-with-ecs-backend/main.d.ts +27 -0
- package/dist/src/construct/site-with-ecs-backend/main.js +31 -1
- package/dist/src/construct/site-with-lambda-backend/main.d.ts +54 -0
- package/dist/src/construct/site-with-lambda-backend/main.js +61 -0
- package/dist/src/construct/static-asset-deployment/main.js +4 -0
- package/dist/src/services/api-gateway/main.js +6 -0
- package/dist/src/services/certificate-manager/main.js +3 -0
- package/dist/src/services/cloudfront/main.d.ts +11 -0
- package/dist/src/services/cloudfront/main.js +11 -0
- package/dist/src/services/cloudtrail/main.js +4 -0
- package/dist/src/services/cloudwatch/main.js +9 -0
- package/dist/src/services/codebuild/main.d.ts +10 -10
- package/dist/src/services/codebuild/main.js +10 -10
- package/dist/src/services/elastic-file-system/main.js +3 -0
- package/dist/src/services/identity-access-management/main.js +5 -0
- package/dist/src/services/lambda/main.d.ts +5 -0
- package/dist/src/services/lambda/main.js +12 -0
- package/dist/src/services/simple-queue-service/main.js +1 -0
- package/dist/src/services/simple-storage-service/main.js +4 -0
- package/dist/src/services/step-function/main.js +5 -0
- package/dist/src/services/systems-manager/main.d.ts +1 -1
- package/dist/src/services/systems-manager/main.js +1 -1
- package/package.json +5 -5
|
@@ -37,6 +37,9 @@ export class EventHandler extends CommonConstruct {
|
|
|
37
37
|
this.id = id;
|
|
38
38
|
this.handler = new Handler();
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* @summary Initialise and provision resources
|
|
42
|
+
*/
|
|
40
43
|
initResources() {
|
|
41
44
|
this.createSQSEventSource();
|
|
42
45
|
this.createWorkflow();
|
|
@@ -107,13 +110,17 @@ export class EventHandler extends CommonConstruct {
|
|
|
107
110
|
* @summary Method to create an event archive if the event rule is not a scheduled one.
|
|
108
111
|
*/
|
|
109
112
|
createEventArchive() {
|
|
110
|
-
/*
|
|
113
|
+
/* Skip archiving when:
|
|
114
|
+
- no event rule is configured
|
|
115
|
+
- the rule is schedule-based (scheduled events are not worth archiving)
|
|
116
|
+
- archiving is explicitly disabled */
|
|
111
117
|
if (!this.props.eventRule ||
|
|
112
118
|
this.props.eventRule.schedule ||
|
|
113
119
|
this.props.eventRuleSchedule ||
|
|
114
120
|
!this.props.eventRuleArchiveEnabled)
|
|
115
121
|
return;
|
|
116
122
|
this.handler.archive = new Archive(this, `${this.id}-archive`, {
|
|
123
|
+
/* Strip the stack name prefix from the archive name to keep it concise */
|
|
117
124
|
archiveName: `${this.props.eventRule.ruleName}-${this.props.stage}`.replace(`${this.node.tryGetContext('stackName')}-`, ''),
|
|
118
125
|
description: `Archive of events for ${this.props.eventRule.ruleName}`,
|
|
119
126
|
eventPattern: this.handler.rulePattern,
|
|
@@ -145,6 +152,10 @@ export class EventHandler extends CommonConstruct {
|
|
|
145
152
|
* @summary Method to create the workflow definition.
|
|
146
153
|
*/
|
|
147
154
|
createWorkflowDefinition() {
|
|
155
|
+
/* When useMapState is true, the workflow uses a Map state to iterate over
|
|
156
|
+
the entire input payload (which must be an array at runtime). The
|
|
157
|
+
eventWorkflowDefinition becomes the iterator (inner step) of the Map
|
|
158
|
+
rather than the top-level state machine definition. */
|
|
148
159
|
if (this.useMapState) {
|
|
149
160
|
this.handler.workflowMapState = new Map(this, `Map Iterator`, {
|
|
150
161
|
...this.props.workflowMapState,
|
|
@@ -43,10 +43,25 @@ export declare class LambdaWithIamAccess extends CommonConstruct {
|
|
|
43
43
|
* @summary Initialise and provision resources
|
|
44
44
|
*/
|
|
45
45
|
initResources(): void;
|
|
46
|
+
/**
|
|
47
|
+
* @summary Resolve the VPC for the Lambda function if a VPC name is provided
|
|
48
|
+
*/
|
|
46
49
|
protected resolveVpc(): void;
|
|
50
|
+
/**
|
|
51
|
+
* @summary Resolve the security groups for the Lambda function from an exported value
|
|
52
|
+
*/
|
|
47
53
|
protected resolveSecurityGroups(): void;
|
|
54
|
+
/**
|
|
55
|
+
* @summary Resolve the EFS access point for the Lambda function. Override to provide an access point.
|
|
56
|
+
*/
|
|
48
57
|
protected resolveAccessPoint(): void;
|
|
58
|
+
/**
|
|
59
|
+
* @summary Resolve the EFS mount path for the Lambda function. Override to provide a mount path.
|
|
60
|
+
*/
|
|
49
61
|
protected resolveMountPath(): void;
|
|
62
|
+
/**
|
|
63
|
+
* @summary Resolve the VPC subnets for the Lambda function. Override to provide specific subnets.
|
|
64
|
+
*/
|
|
50
65
|
protected resolveVpcSubnets(): void;
|
|
51
66
|
/**
|
|
52
67
|
* @summary Method to create iam policy for Lambda function
|
|
@@ -61,11 +61,17 @@ export class LambdaWithIamAccess extends CommonConstruct {
|
|
|
61
61
|
this.createIamUserForLambdaFunction();
|
|
62
62
|
this.createIamSecretForLambdaFunction();
|
|
63
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* @summary Resolve the VPC for the Lambda function if a VPC name is provided
|
|
66
|
+
*/
|
|
64
67
|
resolveVpc() {
|
|
65
68
|
if (this.props.vpcName) {
|
|
66
69
|
this.lambdaVpc = this.vpcManager.retrieveCommonVpc(`${this.id}-vpc`, this, this.props.vpcName);
|
|
67
70
|
}
|
|
68
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* @summary Resolve the security groups for the Lambda function from an exported value
|
|
74
|
+
*/
|
|
69
75
|
resolveSecurityGroups() {
|
|
70
76
|
if (this.props.securityGroupExportName) {
|
|
71
77
|
const lambdaSecurityGroup = SecurityGroup.fromSecurityGroupId(this, `${this.id}-security-group`, Fn.importValue(this.props.securityGroupExportName));
|
|
@@ -73,8 +79,17 @@ export class LambdaWithIamAccess extends CommonConstruct {
|
|
|
73
79
|
this.lambdaSecurityGroups = [lambdaSecurityGroup];
|
|
74
80
|
}
|
|
75
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* @summary Resolve the EFS access point for the Lambda function. Override to provide an access point.
|
|
84
|
+
*/
|
|
76
85
|
resolveAccessPoint() { }
|
|
86
|
+
/**
|
|
87
|
+
* @summary Resolve the EFS mount path for the Lambda function. Override to provide a mount path.
|
|
88
|
+
*/
|
|
77
89
|
resolveMountPath() { }
|
|
90
|
+
/**
|
|
91
|
+
* @summary Resolve the VPC subnets for the Lambda function. Override to provide specific subnets.
|
|
92
|
+
*/
|
|
78
93
|
resolveVpcSubnets() { }
|
|
79
94
|
/**
|
|
80
95
|
* @summary Method to create iam policy for Lambda function
|
|
@@ -140,6 +155,8 @@ export class LambdaWithIamAccess extends CommonConstruct {
|
|
|
140
155
|
this.lambdaIamUser = new User(this, `${this.id}-lambda-user`, {
|
|
141
156
|
userName: this.resourceNameFormatter.format(`${this.id}-user`),
|
|
142
157
|
});
|
|
158
|
+
/* The wildcard suffix on the ARN is needed to match alias-qualified ARNs
|
|
159
|
+
(e.g. arn:...:function:name:aliasName) for InvokeFunction permission */
|
|
143
160
|
new Policy(this, `${this.id}-lambda-user-policy`, {
|
|
144
161
|
policyName: this.resourceNameFormatter.format(`${this.id}-policy`),
|
|
145
162
|
statements: [
|
|
@@ -167,6 +184,8 @@ export class LambdaWithIamAccess extends CommonConstruct {
|
|
|
167
184
|
});
|
|
168
185
|
});
|
|
169
186
|
}
|
|
187
|
+
/* Stage is included in the logical ID to avoid collisions when deploying
|
|
188
|
+
multiple stages to the same AWS account */
|
|
170
189
|
this.lambdaUserAccessKey = new CfnAccessKey(this, `${this.id}-access-key-${this.props.stage}`, {
|
|
171
190
|
userName: this.lambdaIamUser.userName,
|
|
172
191
|
});
|
|
@@ -176,6 +195,9 @@ export class LambdaWithIamAccess extends CommonConstruct {
|
|
|
176
195
|
*/
|
|
177
196
|
createIamSecretForLambdaFunction() {
|
|
178
197
|
this.lambdaUserAccessSecret = this.secretsManager.createSecret(`${this.id}-lambda-user-secret-${this.props.stage}`, this, this.props.lambdaSecret);
|
|
198
|
+
/* Override the L1 CfnSecret to disable auto-generated secret string and inject
|
|
199
|
+
the IAM access key credentials instead. We use a template literal (not JSON.stringify)
|
|
200
|
+
because the values contain CloudFormation Ref/GetAtt tokens that must not be escaped. */
|
|
179
201
|
const cfnSecret = this.lambdaUserAccessSecret.node.defaultChild;
|
|
180
202
|
cfnSecret.generateSecretString = undefined;
|
|
181
203
|
cfnSecret.secretString = `{ "ACCESS_KEY_ID": "${this.lambdaUserAccessKey.ref}", "ACCESS_KEY_SECRET": "${this.lambdaUserAccessKey.attrSecretAccessKey}" }`;
|
|
@@ -23,6 +23,9 @@ export declare class PipedEventHandler extends EventHandler {
|
|
|
23
23
|
pipedDlq: IQueue;
|
|
24
24
|
pipedQueue: IQueue;
|
|
25
25
|
protected constructor(parent: Construct, id: string, props: PipedEventHandlerProps);
|
|
26
|
+
/**
|
|
27
|
+
* @summary Initialise and provision resources
|
|
28
|
+
*/
|
|
26
29
|
initResources(): void;
|
|
27
30
|
/**
|
|
28
31
|
* @summary Method to create the piped queue and dlq.
|
|
@@ -28,6 +28,9 @@ export class PipedEventHandler extends EventHandler {
|
|
|
28
28
|
this.useMapState = true;
|
|
29
29
|
this.provisionTarget = false;
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* @summary Initialise and provision resources
|
|
33
|
+
*/
|
|
31
34
|
initResources() {
|
|
32
35
|
this.createPipedQueue();
|
|
33
36
|
this.handler.sqsTargets = [new SqsQueue(this.pipedQueue)];
|
|
@@ -76,6 +76,9 @@ export class RestApiLambda extends CommonConstruct {
|
|
|
76
76
|
* @summary Method to resolve a certificate based on attributes
|
|
77
77
|
*/
|
|
78
78
|
resolveCertificate() {
|
|
79
|
+
/* ACM certificates for CloudFront must be in us-east-1, which may differ from the
|
|
80
|
+
stack's region. When an SSM parameter name and region are provided, the ARN is
|
|
81
|
+
read cross-region and mutated onto the props before certificate resolution. */
|
|
79
82
|
if (this.props.restApiCertificate.useExistingCertificate &&
|
|
80
83
|
this.props.restApiCertificate.certificateSsmName &&
|
|
81
84
|
this.props.restApiCertificate.certificateRegion) {
|
|
@@ -29,6 +29,9 @@ export declare abstract class RestApiLambdaWithCache extends RestApiLambda {
|
|
|
29
29
|
restApiSecurityGroup: ISecurityGroup;
|
|
30
30
|
restApiSecurityGroupExportName: string;
|
|
31
31
|
protected constructor(parent: Construct, id: string, props: RestApiLambdaWithCacheProps);
|
|
32
|
+
/**
|
|
33
|
+
* @summary Initialise and provision resources
|
|
34
|
+
*/
|
|
32
35
|
initResources(): void;
|
|
33
36
|
/**
|
|
34
37
|
* Create VPC
|
|
@@ -75,7 +75,13 @@ export declare class SiteWithEcsBackend extends CommonConstruct {
|
|
|
75
75
|
* @summary Method to resolve a certificate based on attributes
|
|
76
76
|
*/
|
|
77
77
|
protected resolveCertificate(): void;
|
|
78
|
+
/**
|
|
79
|
+
* @summary Resolve the global (edge) SSL certificate, optionally reading the ARN from SSM
|
|
80
|
+
*/
|
|
78
81
|
protected resolveGlobalCertificate(): void;
|
|
82
|
+
/**
|
|
83
|
+
* @summary Resolve the regional SSL certificate, optionally reading the ARN from SSM
|
|
84
|
+
*/
|
|
79
85
|
protected resolveRegionalCertificate(): void;
|
|
80
86
|
/**
|
|
81
87
|
* @summary Method to resolve secrets from SecretsManager
|
|
@@ -126,11 +132,32 @@ export declare class SiteWithEcsBackend extends CommonConstruct {
|
|
|
126
132
|
* Method to create log bucket for site distribution
|
|
127
133
|
*/
|
|
128
134
|
protected createSiteLogBucket(): void;
|
|
135
|
+
/**
|
|
136
|
+
* @summary Create a CloudFront cache policy with the specified TTL and behaviour settings
|
|
137
|
+
* @param id scoped id of the resource
|
|
138
|
+
* @param siteCachePolicy the cache policy properties
|
|
139
|
+
*/
|
|
129
140
|
protected createSiteCachePolicy(id: string, siteCachePolicy: SiteCachePolicyProps): CachePolicy;
|
|
141
|
+
/**
|
|
142
|
+
* @summary Create the cache policy for the site origin and assign it to the default behaviour
|
|
143
|
+
*/
|
|
130
144
|
protected createSiteOriginCachePolicy(): void;
|
|
145
|
+
/**
|
|
146
|
+
* @summary Create the origin request policy for the site distribution
|
|
147
|
+
*/
|
|
131
148
|
protected createSiteOriginRequestPolicy(): void;
|
|
149
|
+
/**
|
|
150
|
+
* @summary Create a CloudFront response headers policy with security headers
|
|
151
|
+
* @param props the response headers policy properties
|
|
152
|
+
*/
|
|
132
153
|
protected createResponseHeaderPolicy(props: SiteResponseHeadersPolicyProps): ResponseHeadersPolicy | undefined;
|
|
154
|
+
/**
|
|
155
|
+
* @summary Create the response headers policy for the site origin and assign it to the default behaviour
|
|
156
|
+
*/
|
|
133
157
|
protected createSiteOriginResponseHeadersPolicy(): void;
|
|
158
|
+
/**
|
|
159
|
+
* @summary Create the HTTP origin pointing to the ECS backend service
|
|
160
|
+
*/
|
|
134
161
|
protected createSiteOrigin(): void;
|
|
135
162
|
/**
|
|
136
163
|
* @summary Method to create a site cloudfront function
|
|
@@ -102,6 +102,9 @@ export class SiteWithEcsBackend extends CommonConstruct {
|
|
|
102
102
|
this.resolveGlobalCertificate();
|
|
103
103
|
this.resolveRegionalCertificate();
|
|
104
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* @summary Resolve the global (edge) SSL certificate, optionally reading the ARN from SSM
|
|
107
|
+
*/
|
|
105
108
|
resolveGlobalCertificate() {
|
|
106
109
|
if (this.props.siteCertificate.useExistingCertificate &&
|
|
107
110
|
this.props.siteCertificate.certificateSsmName &&
|
|
@@ -110,6 +113,9 @@ export class SiteWithEcsBackend extends CommonConstruct {
|
|
|
110
113
|
}
|
|
111
114
|
this.siteCertificate = this.acmManager.resolveCertificate(`${this.id}-certificate`, this, this.props.siteCertificate);
|
|
112
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* @summary Resolve the regional SSL certificate, optionally reading the ARN from SSM
|
|
118
|
+
*/
|
|
113
119
|
resolveRegionalCertificate() {
|
|
114
120
|
if (this.props.siteRegionalCertificate.useExistingCertificate &&
|
|
115
121
|
this.props.siteRegionalCertificate.certificateSsmName &&
|
|
@@ -257,6 +263,8 @@ export class SiteWithEcsBackend extends CommonConstruct {
|
|
|
257
263
|
this.siteEcsLoadBalancer = fargateService.loadBalancer;
|
|
258
264
|
this.siteEcsTargetGroup = fargateService.targetGroup;
|
|
259
265
|
fargateService.loadBalancer.logAccessLogs(this.siteLogBucket, 'alb');
|
|
266
|
+
/* Configure auto-scaling policies — each scaling dimension is independent
|
|
267
|
+
and only enabled when its corresponding threshold is set in props */
|
|
260
268
|
if (this.props.siteTask.siteScaling) {
|
|
261
269
|
const scalableTaskCount = this.siteEcsService.autoScaleTaskCount({
|
|
262
270
|
maxCapacity: this.props.siteTask.siteScaling.maxCapacity ?? 4,
|
|
@@ -285,7 +293,8 @@ export class SiteWithEcsBackend extends CommonConstruct {
|
|
|
285
293
|
/* if enabled, add efs with access point and mount */
|
|
286
294
|
if (this.props.siteFileSystem) {
|
|
287
295
|
this.siteFileSystem = this.efsManager.createFileSystem(`${this.id}-fs`, this, this.props.siteFileSystem, this.siteVpc, this.props.siteFileSystemAccessPoints);
|
|
288
|
-
/*
|
|
296
|
+
/* Allow bidirectional NFS traffic between EFS and the Fargate service —
|
|
297
|
+
both directions are required for the EFS mount to function correctly */
|
|
289
298
|
this.siteFileSystem.connections.allowDefaultPortFrom(this.siteEcsService.connections);
|
|
290
299
|
this.siteFileSystem.connections.allowDefaultPortTo(this.siteEcsService.connections);
|
|
291
300
|
/* add EFS permissions to ECS Role */
|
|
@@ -322,6 +331,11 @@ export class SiteWithEcsBackend extends CommonConstruct {
|
|
|
322
331
|
createSiteLogBucket() {
|
|
323
332
|
this.siteLogBucket = this.s3Manager.createS3Bucket(`${this.id}-site-logs`, this, this.props.siteLogBucket);
|
|
324
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* @summary Create a CloudFront cache policy with the specified TTL and behaviour settings
|
|
336
|
+
* @param id scoped id of the resource
|
|
337
|
+
* @param siteCachePolicy the cache policy properties
|
|
338
|
+
*/
|
|
325
339
|
createSiteCachePolicy(id, siteCachePolicy) {
|
|
326
340
|
if (!siteCachePolicy.cachePolicyName)
|
|
327
341
|
throw new Error(`SiteCachePolicy cachePolicyName undefined for ${id}`);
|
|
@@ -337,6 +351,9 @@ export class SiteWithEcsBackend extends CommonConstruct {
|
|
|
337
351
|
queryStringBehavior: siteCachePolicy.queryStringBehavior,
|
|
338
352
|
});
|
|
339
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* @summary Create the cache policy for the site origin and assign it to the default behaviour
|
|
356
|
+
*/
|
|
340
357
|
createSiteOriginCachePolicy() {
|
|
341
358
|
if (!this.props.siteCachePolicy)
|
|
342
359
|
return;
|
|
@@ -345,6 +362,9 @@ export class SiteWithEcsBackend extends CommonConstruct {
|
|
|
345
362
|
cachePolicy: this.siteCachePolicy,
|
|
346
363
|
});
|
|
347
364
|
}
|
|
365
|
+
/**
|
|
366
|
+
* @summary Create the origin request policy for the site distribution
|
|
367
|
+
*/
|
|
348
368
|
createSiteOriginRequestPolicy() {
|
|
349
369
|
if (!this.props.siteOriginRequestPolicy)
|
|
350
370
|
return;
|
|
@@ -361,6 +381,10 @@ export class SiteWithEcsBackend extends CommonConstruct {
|
|
|
361
381
|
originRequestPolicy: this.siteOriginRequestPolicy,
|
|
362
382
|
});
|
|
363
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* @summary Create a CloudFront response headers policy with security headers
|
|
386
|
+
* @param props the response headers policy properties
|
|
387
|
+
*/
|
|
364
388
|
createResponseHeaderPolicy(props) {
|
|
365
389
|
if (!props)
|
|
366
390
|
return undefined;
|
|
@@ -379,6 +403,9 @@ export class SiteWithEcsBackend extends CommonConstruct {
|
|
|
379
403
|
},
|
|
380
404
|
});
|
|
381
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* @summary Create the response headers policy for the site origin and assign it to the default behaviour
|
|
408
|
+
*/
|
|
382
409
|
createSiteOriginResponseHeadersPolicy() {
|
|
383
410
|
if (!this.props.siteOriginResponseHeadersPolicy)
|
|
384
411
|
return;
|
|
@@ -387,6 +414,9 @@ export class SiteWithEcsBackend extends CommonConstruct {
|
|
|
387
414
|
responseHeadersPolicy: this.siteOriginResponseHeadersPolicy,
|
|
388
415
|
});
|
|
389
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* @summary Create the HTTP origin pointing to the ECS backend service
|
|
419
|
+
*/
|
|
390
420
|
createSiteOrigin() {
|
|
391
421
|
this.siteOrigin = new HttpOrigin(this.siteInternalDomainName, {
|
|
392
422
|
httpPort: this.props.siteTask.listenerPort,
|
|
@@ -64,7 +64,13 @@ export declare class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
64
64
|
* @summary Method to resolve a certificate based on attributes
|
|
65
65
|
*/
|
|
66
66
|
protected resolveCertificate(): void;
|
|
67
|
+
/**
|
|
68
|
+
* @summary Resolve the global (edge) SSL certificate, optionally reading the ARN from SSM
|
|
69
|
+
*/
|
|
67
70
|
protected resolveGlobalCertificate(): void;
|
|
71
|
+
/**
|
|
72
|
+
* @summary Resolve the regional SSL certificate, optionally reading the ARN from SSM
|
|
73
|
+
*/
|
|
68
74
|
protected resolveRegionalCertificate(): void;
|
|
69
75
|
/**
|
|
70
76
|
* @summary Method to resolve secrets from SecretsManager
|
|
@@ -79,20 +85,68 @@ export declare class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
79
85
|
* Method to create log bucket for site distribution
|
|
80
86
|
*/
|
|
81
87
|
protected createSiteLogBucket(): void;
|
|
88
|
+
/**
|
|
89
|
+
* @summary Create a CloudFront cache policy with the specified TTL and behaviour settings
|
|
90
|
+
* @param id scoped id of the resource
|
|
91
|
+
* @param siteCachePolicy the cache policy properties
|
|
92
|
+
*/
|
|
82
93
|
protected createSiteCachePolicy(id: string, siteCachePolicy: SiteWithLambdaBackendCachePolicyProps): CachePolicy;
|
|
94
|
+
/**
|
|
95
|
+
* @summary Create the cache policy for the site origin and assign it to the default behaviour
|
|
96
|
+
*/
|
|
83
97
|
protected createSiteOriginCachePolicy(): void;
|
|
98
|
+
/**
|
|
99
|
+
* @summary Create the origin request policy for the site distribution
|
|
100
|
+
*/
|
|
84
101
|
protected createSiteOriginRequestPolicy(): void;
|
|
102
|
+
/**
|
|
103
|
+
* @summary Create a CloudFront response headers policy with security headers
|
|
104
|
+
* @param props the response headers policy properties
|
|
105
|
+
*/
|
|
85
106
|
protected createResponseHeaderPolicy(props: SiteWithLambdaBackendResponseHeadersPolicyProps): ResponseHeadersPolicy | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* @summary Create the response headers policy for the site origin and assign it to the default behaviour
|
|
109
|
+
*/
|
|
86
110
|
protected createSiteOriginResponseHeadersPolicy(): void;
|
|
111
|
+
/**
|
|
112
|
+
* @summary Create the HTTP origin backed by the Lambda function URL
|
|
113
|
+
*/
|
|
87
114
|
protected createSiteOrigin(): void;
|
|
115
|
+
/**
|
|
116
|
+
* @summary Orchestrate creation of all Lambda-based origin resources
|
|
117
|
+
*/
|
|
88
118
|
protected createSiteOriginResources(): void;
|
|
119
|
+
/**
|
|
120
|
+
* @summary Create static asset deployment. Override to provide a deployment.
|
|
121
|
+
*/
|
|
89
122
|
protected createSiteStaticAssetDeployment(): void;
|
|
123
|
+
/**
|
|
124
|
+
* @summary Create the IAM policy for the site Lambda function
|
|
125
|
+
*/
|
|
90
126
|
protected createSiteLambdaPolicy(): void;
|
|
127
|
+
/**
|
|
128
|
+
* @summary Create the IAM role for the site Lambda function
|
|
129
|
+
*/
|
|
91
130
|
protected createSiteLambdaRole(): void;
|
|
131
|
+
/**
|
|
132
|
+
* @summary Create the environment variables for the site Lambda function including Web Adapter config
|
|
133
|
+
*/
|
|
92
134
|
protected createSiteLambdaEnvironment(): void;
|
|
135
|
+
/**
|
|
136
|
+
* @summary Create the Lambda Web Adapter layers for the site function
|
|
137
|
+
*/
|
|
93
138
|
protected createSiteLambdaLayers(): void;
|
|
139
|
+
/**
|
|
140
|
+
* @summary Create the Lambda application code. Override to provide custom application code.
|
|
141
|
+
*/
|
|
94
142
|
protected createSiteLambdaApplication(): void;
|
|
143
|
+
/**
|
|
144
|
+
* @summary Create the site Lambda function with the configured role, layers, and environment
|
|
145
|
+
*/
|
|
95
146
|
protected createSiteLambda(): void;
|
|
147
|
+
/**
|
|
148
|
+
* @summary Create the Lambda function URL used as the CloudFront origin, with optional alias support
|
|
149
|
+
*/
|
|
96
150
|
protected createSiteLambdaUrl(): void;
|
|
97
151
|
/**
|
|
98
152
|
* @summary Method to create a site cloudfront function
|
|
@@ -87,6 +87,9 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
87
87
|
this.resolveGlobalCertificate();
|
|
88
88
|
this.resolveRegionalCertificate();
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* @summary Resolve the global (edge) SSL certificate, optionally reading the ARN from SSM
|
|
92
|
+
*/
|
|
90
93
|
resolveGlobalCertificate() {
|
|
91
94
|
if (this.props.siteCertificate.useExistingCertificate &&
|
|
92
95
|
this.props.siteCertificate.certificateSsmName &&
|
|
@@ -95,6 +98,9 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
95
98
|
}
|
|
96
99
|
this.siteCertificate = this.acmManager.resolveCertificate(`${this.id}-certificate`, this, this.props.siteCertificate);
|
|
97
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* @summary Resolve the regional SSL certificate, optionally reading the ARN from SSM
|
|
103
|
+
*/
|
|
98
104
|
resolveRegionalCertificate() {
|
|
99
105
|
if (this.props.siteRegionalCertificate.useExistingCertificate &&
|
|
100
106
|
this.props.siteRegionalCertificate.certificateSsmName &&
|
|
@@ -130,6 +136,11 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
130
136
|
createSiteLogBucket() {
|
|
131
137
|
this.siteLogBucket = this.s3Manager.createS3Bucket(`${this.id}-site-logs`, this, this.props.siteLogBucket);
|
|
132
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* @summary Create a CloudFront cache policy with the specified TTL and behaviour settings
|
|
141
|
+
* @param id scoped id of the resource
|
|
142
|
+
* @param siteCachePolicy the cache policy properties
|
|
143
|
+
*/
|
|
133
144
|
createSiteCachePolicy(id, siteCachePolicy) {
|
|
134
145
|
if (!siteCachePolicy.cachePolicyName)
|
|
135
146
|
throw new Error(`SiteCachePolicy cachePolicyName undefined for ${id}`);
|
|
@@ -145,6 +156,9 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
145
156
|
queryStringBehavior: siteCachePolicy.queryStringBehavior,
|
|
146
157
|
});
|
|
147
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* @summary Create the cache policy for the site origin and assign it to the default behaviour
|
|
161
|
+
*/
|
|
148
162
|
createSiteOriginCachePolicy() {
|
|
149
163
|
if (!this.props.siteCachePolicy)
|
|
150
164
|
return;
|
|
@@ -153,6 +167,9 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
153
167
|
cachePolicy: this.siteCachePolicy,
|
|
154
168
|
});
|
|
155
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* @summary Create the origin request policy for the site distribution
|
|
172
|
+
*/
|
|
156
173
|
createSiteOriginRequestPolicy() {
|
|
157
174
|
if (!this.props.siteOriginRequestPolicy)
|
|
158
175
|
return;
|
|
@@ -169,6 +186,10 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
169
186
|
originRequestPolicy: this.siteOriginRequestPolicy,
|
|
170
187
|
});
|
|
171
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* @summary Create a CloudFront response headers policy with security headers
|
|
191
|
+
* @param props the response headers policy properties
|
|
192
|
+
*/
|
|
172
193
|
createResponseHeaderPolicy(props) {
|
|
173
194
|
if (!props)
|
|
174
195
|
return undefined;
|
|
@@ -187,6 +208,9 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
187
208
|
},
|
|
188
209
|
});
|
|
189
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* @summary Create the response headers policy for the site origin and assign it to the default behaviour
|
|
213
|
+
*/
|
|
190
214
|
createSiteOriginResponseHeadersPolicy() {
|
|
191
215
|
if (!this.props.siteOriginResponseHeadersPolicy)
|
|
192
216
|
return;
|
|
@@ -195,6 +219,9 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
195
219
|
responseHeadersPolicy: this.siteOriginResponseHeadersPolicy,
|
|
196
220
|
});
|
|
197
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* @summary Create the HTTP origin backed by the Lambda function URL
|
|
224
|
+
*/
|
|
198
225
|
createSiteOrigin() {
|
|
199
226
|
this.createSiteOriginResources();
|
|
200
227
|
this.siteOrigin = new HttpOrigin(Fn.select(2, Fn.split('/', this.siteLambdaUrl.url)), {
|
|
@@ -203,6 +230,9 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
203
230
|
protocolPolicy: OriginProtocolPolicy.HTTPS_ONLY,
|
|
204
231
|
});
|
|
205
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* @summary Orchestrate creation of all Lambda-based origin resources
|
|
235
|
+
*/
|
|
206
236
|
createSiteOriginResources() {
|
|
207
237
|
this.createSiteStaticAssetDeployment();
|
|
208
238
|
this.createSiteLambdaPolicy();
|
|
@@ -213,7 +243,13 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
213
243
|
this.createSiteLambda();
|
|
214
244
|
this.createSiteLambdaUrl();
|
|
215
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* @summary Create static asset deployment. Override to provide a deployment.
|
|
248
|
+
*/
|
|
216
249
|
createSiteStaticAssetDeployment() { }
|
|
250
|
+
/**
|
|
251
|
+
* @summary Create the IAM policy for the site Lambda function
|
|
252
|
+
*/
|
|
217
253
|
createSiteLambdaPolicy() {
|
|
218
254
|
this.siteLambdaPolicy = new PolicyDocument({
|
|
219
255
|
statements: [
|
|
@@ -225,9 +261,15 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
225
261
|
],
|
|
226
262
|
});
|
|
227
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* @summary Create the IAM role for the site Lambda function
|
|
266
|
+
*/
|
|
228
267
|
createSiteLambdaRole() {
|
|
229
268
|
this.siteLambdaRole = this.iamManager.createRoleForLambda(`${this.id}-role`, this, this.siteLambdaPolicy);
|
|
230
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* @summary Create the environment variables for the site Lambda function including Web Adapter config
|
|
272
|
+
*/
|
|
231
273
|
createSiteLambdaEnvironment() {
|
|
232
274
|
this.siteLambdaEnvironment = {
|
|
233
275
|
AWS_LAMBDA_EXEC_WRAPPER: this.props.siteExecWrapperPath ?? '/opt/bootstrap',
|
|
@@ -240,15 +282,31 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
240
282
|
TZ: this.props.timezone,
|
|
241
283
|
};
|
|
242
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* @summary Create the Lambda Web Adapter layers for the site function
|
|
287
|
+
*/
|
|
243
288
|
createSiteLambdaLayers() {
|
|
244
289
|
this.siteLambdaLayers = this.lambdaManager.createWebAdapterLayer(`${this.id}-web-adapter`, this);
|
|
245
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* @summary Create the Lambda application code. Override to provide custom application code.
|
|
293
|
+
*/
|
|
246
294
|
createSiteLambdaApplication() { }
|
|
295
|
+
/**
|
|
296
|
+
* @summary Create the site Lambda function with the configured role, layers, and environment
|
|
297
|
+
*/
|
|
247
298
|
createSiteLambda() {
|
|
248
299
|
this.siteLambdaFunction = this.lambdaManager.createLambdaFunction(`${this.id}-lambda`, this, this.props.siteLambda, this.siteLambdaRole, this.siteLambdaLayers, this.siteLambdaApplication, this.props.siteLambda.handler, this.siteLambdaEnvironment);
|
|
249
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* @summary Create the Lambda function URL used as the CloudFront origin, with optional alias support
|
|
303
|
+
*/
|
|
250
304
|
createSiteLambdaUrl() {
|
|
305
|
+
/* Check if a 'current' alias is configured — when present, the function URL
|
|
306
|
+
points to the alias ARN (functionArn:aliasName) instead of $LATEST */
|
|
251
307
|
const lambdaAlias = _.find(this.props.siteLambda.lambdaAliases, alias => alias.aliasName === LAMBDA_ALIAS_NAME_CURRENT);
|
|
308
|
+
/* When using an alias, import the function with sameEnvironment: true to
|
|
309
|
+
prevent CDK from generating cross-account/cross-region permissions */
|
|
252
310
|
const lambdaFn = lambdaAlias
|
|
253
311
|
? Function.fromFunctionAttributes(this, `${this.id}-fn-alias`, {
|
|
254
312
|
functionArn: `${this.siteLambdaFunction.functionArn}:${lambdaAlias.aliasName}`,
|
|
@@ -256,11 +314,14 @@ export class SiteWithLambdaBackend extends CommonConstruct {
|
|
|
256
314
|
})
|
|
257
315
|
: this.siteLambdaFunction;
|
|
258
316
|
lambdaFn.node.addDependency(this.siteLambdaFunction);
|
|
317
|
+
/* Explicit dependencies ensure the function and alias exist before the URL is created */
|
|
259
318
|
this.siteLambdaUrl = lambdaFn.addFunctionUrl({
|
|
260
319
|
authType: FunctionUrlAuthType.NONE,
|
|
261
320
|
});
|
|
262
321
|
this.siteLambdaUrl.node.addDependency(this.siteLambdaFunction);
|
|
263
322
|
this.siteLambdaUrl.node.addDependency(lambdaFn);
|
|
323
|
+
/* Grant public invoke access — the resource-based policy is applied via
|
|
324
|
+
grantInvokeUrl, restricted by the FunctionUrlAuthType condition */
|
|
264
325
|
const principal = new AnyPrincipal();
|
|
265
326
|
principal.addToPolicy(new PolicyStatement({
|
|
266
327
|
actions: ['lambda:InvokeFunctionUrl'],
|
|
@@ -71,6 +71,8 @@ export class StaticAssetDeployment extends CommonConstruct {
|
|
|
71
71
|
* @summary Deploy the static assets into the static asset bucket
|
|
72
72
|
*/
|
|
73
73
|
deployStaticAssets() {
|
|
74
|
+
/* Sources can be provided as either string paths (resolved relative to the
|
|
75
|
+
project root) or pre-built ISource objects for more flexibility */
|
|
74
76
|
let sources = [];
|
|
75
77
|
if (Array.isArray(this.props.staticAssetSources) &&
|
|
76
78
|
this.props.staticAssetSources.length > 0 &&
|
|
@@ -83,6 +85,8 @@ export class StaticAssetDeployment extends CommonConstruct {
|
|
|
83
85
|
else {
|
|
84
86
|
sources = this.props.staticAssetSources;
|
|
85
87
|
}
|
|
88
|
+
/* Build optional config objects as empty objects and conditionally populate them,
|
|
89
|
+
then spread into the deployment — this avoids setting undefined properties */
|
|
86
90
|
let distributionOptions = {};
|
|
87
91
|
if (this.cloudfrontDistribution) {
|
|
88
92
|
distributionOptions = {
|
|
@@ -105,6 +105,8 @@ export class ApiManager {
|
|
|
105
105
|
*/
|
|
106
106
|
createApiResource(id, scope, parent, path, integration, addProxy, authorizer, allowedOrigins, allowedMethods, allowedHeaders, methodRequestParameters, proxyIntegration, enableDefaultCors, mockIntegration, mockMethodResponses) {
|
|
107
107
|
const methods = allowedMethods ?? Cors.ALL_METHODS;
|
|
108
|
+
/* enableDefaultCors uses strict equality — only `false` disables CORS.
|
|
109
|
+
When CORS is disabled, OPTIONS requests are routed to the mock integration instead. */
|
|
108
110
|
let defaultCorsPreflightOptions;
|
|
109
111
|
if (enableDefaultCors === false) {
|
|
110
112
|
defaultCorsPreflightOptions = undefined;
|
|
@@ -120,6 +122,8 @@ export class ApiManager {
|
|
|
120
122
|
const resource = parent.addResource(path, {
|
|
121
123
|
defaultCorsPreflightOptions: defaultCorsPreflightOptions,
|
|
122
124
|
});
|
|
125
|
+
/* When CORS is disabled, route OPTIONS to the mock integration for manual
|
|
126
|
+
CORS handling; all other methods use the real integration */
|
|
123
127
|
_.forEach(methods, method => {
|
|
124
128
|
if (enableDefaultCors === false && mockIntegration && method === 'OPTIONS') {
|
|
125
129
|
resource.addMethod(method, mockIntegration, {
|
|
@@ -136,6 +140,8 @@ export class ApiManager {
|
|
|
136
140
|
}
|
|
137
141
|
});
|
|
138
142
|
createCfnOutput(`${id}-${path}ResourceId`, scope, resource.resourceId);
|
|
143
|
+
/* Create a greedy proxy resource ({path+}) to catch all sub-paths.
|
|
144
|
+
Uses proxyIntegration if provided, otherwise falls back to the main integration. */
|
|
139
145
|
if (addProxy) {
|
|
140
146
|
const resourceProxy = resource.addResource(`{${path}+}`, {
|
|
141
147
|
defaultCorsPreflightOptions: defaultCorsPreflightOptions,
|
|
@@ -43,6 +43,9 @@ export class AcmManager {
|
|
|
43
43
|
throw new Error(`Certificate props undefined for ${id}`);
|
|
44
44
|
let certificate;
|
|
45
45
|
if (props.useExistingCertificate) {
|
|
46
|
+
/* When importing an existing certificate, the ARN can be provided directly
|
|
47
|
+
or constructed from account/region/id — falls back to the current stack's
|
|
48
|
+
account and region when not explicitly specified */
|
|
46
49
|
let certificateArn = props.certificateArn;
|
|
47
50
|
if (!certificateArn) {
|
|
48
51
|
const certificateAccount = props.certificateAccount ? props.certificateAccount : Stack.of(scope).account;
|
|
@@ -35,6 +35,12 @@ import { CloudfrontFunctionProps, DistributionProps } from './types.js';
|
|
|
35
35
|
* @category Service
|
|
36
36
|
*/
|
|
37
37
|
export declare class CloudFrontManager {
|
|
38
|
+
/**
|
|
39
|
+
* @summary Method to create a CloudFront Origin Access Identity
|
|
40
|
+
* @param id scoped id of the resource
|
|
41
|
+
* @param scope scope in which this resource is defined
|
|
42
|
+
* @param accessBucket optional S3 bucket to grant read access to the OAI
|
|
43
|
+
*/
|
|
38
44
|
createOriginAccessIdentity(id: string, scope: CommonConstruct, accessBucket?: IBucket): cf.OriginAccessIdentity;
|
|
39
45
|
/**
|
|
40
46
|
* Method to create a CloudFront distribution with S3 Origin
|
|
@@ -93,5 +99,10 @@ export declare class CloudFrontManager {
|
|
|
93
99
|
* @param props
|
|
94
100
|
*/
|
|
95
101
|
createCloudfrontFunction(id: string, scope: CommonConstruct, props: CloudfrontFunctionProps): cf.Function;
|
|
102
|
+
/**
|
|
103
|
+
* @summary Method to resolve an existing CloudFront distribution by its attributes
|
|
104
|
+
* @param scope scope in which this resource is defined
|
|
105
|
+
* @param props the distribution attributes to look up
|
|
106
|
+
*/
|
|
96
107
|
resolveDistribution(scope: CommonConstruct, props: DistributionAttributes): IDistribution;
|
|
97
108
|
}
|