Skip to content

Commit 3a090dc

Browse files
bshrramfwang
andauthored
NextjsSite: make image regenerator customizable (#1250)
* fix(nextJsStie): make regenerator function customizable * Sync * Allow customizing regeneration queue Co-authored-by: Frank <wangfanjie@gmail.com>
1 parent 958243a commit 3a090dc

File tree

3 files changed

+49
-13
lines changed

3 files changed

+49
-13
lines changed

packages/resources/src/NextjsSite.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import * as crossRegionHelper from "./nextjs-site/cross-region-helper";
3838
export interface NextjsSiteProps {
3939
path: string;
4040
s3Bucket?: s3.BucketProps;
41+
sqsRegenerationQueue?: sqs.QueueProps;
4142
customDomain?: string | NextjsSiteDomainProps;
4243
cfCachePolicies?: NextjsSiteCachePolicyProps;
4344
cfDistribution?: NextjsSiteCdkDistributionProps;
@@ -99,6 +100,7 @@ export class NextjsSite extends Construct implements SSTConstruct {
99100
};
100101

101102
public readonly s3Bucket: s3.Bucket;
103+
public readonly sqsRegenerationQueue: sqs.Queue;
102104
public readonly cfDistribution: cloudfront.Distribution;
103105
public readonly hostedZone?: route53.IHostedZone;
104106
public readonly acmCertificate?: acm.ICertificate;
@@ -113,7 +115,6 @@ export class NextjsSite extends Construct implements SSTConstruct {
113115
private readonly mainFunctionVersion: lambda.IVersion;
114116
private readonly apiFunctionVersion: lambda.IVersion;
115117
private readonly imageFunctionVersion: lambda.IVersion;
116-
private readonly regenerationQueue: sqs.Queue;
117118
private readonly regenerationFunction: lambda.Function;
118119

119120
constructor(scope: Construct, id: string, props: NextjsSiteProps) {
@@ -157,7 +158,7 @@ export class NextjsSite extends Construct implements SSTConstruct {
157158
this.s3Bucket = this.createS3Bucket();
158159

159160
// Handle Incremental Static Regeneration
160-
this.regenerationQueue = this.createRegenerationQueue();
161+
this.sqsRegenerationQueue = this.createRegenerationQueue();
161162
this.regenerationFunction = this.createRegenerationFunction();
162163

163164
// Create Lambda@Edge functions (always created in us-east-1)
@@ -434,7 +435,7 @@ export class NextjsSite extends Construct implements SSTConstruct {
434435

435436
// Attach permission
436437
this.s3Bucket.grantReadWrite(role);
437-
this.regenerationQueue.grantSendMessages(role);
438+
this.sqsRegenerationQueue.grantSendMessages(role);
438439
this.regenerationFunction.grantInvoke(role);
439440
if (fnProps?.permissions) {
440441
attachPermissionsToRole(role, fnProps.permissions);
@@ -444,7 +445,10 @@ export class NextjsSite extends Construct implements SSTConstruct {
444445
}
445446

446447
private createRegenerationQueue(): sqs.Queue {
448+
const { sqsRegenerationQueue } = this.props;
449+
447450
return new sqs.Queue(this, "RegenerationQueue", {
451+
...(sqsRegenerationQueue || {}),
448452
// We call the queue the same name as the bucket so that we can easily
449453
// reference it from within the lambda@edge, given we can't use env vars
450454
// in a lambda@edge
@@ -477,15 +481,18 @@ export class NextjsSite extends Construct implements SSTConstruct {
477481
code = lambda.Code.fromInline(" ");
478482
}
479483

484+
// Create function
485+
const { defaultFunctionProps: fnProps } = this.props;
480486
const fn = new lambda.Function(this, "RegenerationFunction", {
481487
handler: "index.handler",
482488
runtime: lambda.Runtime.NODEJS_12_X,
483-
timeout: cdk.Duration.seconds(30),
489+
memorySize: fnProps?.memorySize || 1024,
490+
timeout: cdk.Duration.seconds(fnProps?.timeout || 30),
484491
code,
485492
});
486493

487494
fn.addEventSource(
488-
new lambdaEventSources.SqsEventSource(this.regenerationQueue)
495+
new lambdaEventSources.SqsEventSource(this.sqsRegenerationQueue)
489496
);
490497

491498
// Grant permissions
@@ -606,14 +613,13 @@ export class NextjsSite extends Construct implements SSTConstruct {
606613
}
607614

608615
private createS3Bucket(): s3.Bucket {
609-
let { s3Bucket } = this.props;
610-
s3Bucket = s3Bucket || {};
616+
const { s3Bucket } = this.props;
611617

612618
return new s3.Bucket(this, "Bucket", {
613619
publicReadAccess: true,
614620
autoDeleteObjects: true,
615621
removalPolicy: cdk.RemovalPolicy.DESTROY,
616-
...s3Bucket,
622+
...(s3Bucket || {}),
617623
});
618624
}
619625

packages/resources/test/NextjsSite.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
ANY,
1313
ABSENT,
1414
} from "./helper";
15+
import * as cdk from "aws-cdk-lib";
1516
import * as cf from "aws-cdk-lib/aws-cloudfront";
1617
import * as route53 from "aws-cdk-lib/aws-route53";
1718
import * as acm from "aws-cdk-lib/aws-certificatemanager";
@@ -693,6 +694,23 @@ test("constructor: s3Bucket props", async () => {
693694
});
694695
});
695696

697+
test("constructor: sqsRegenerationQueue props", async () => {
698+
const stack = new Stack(new App(), "stack");
699+
new NextjsSite(stack, "Site", {
700+
path: "test/nextjs-site",
701+
sqsRegenerationQueue: {
702+
deliveryDelay: cdk.Duration.seconds(30),
703+
},
704+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
705+
// @ts-ignore: "jestBuildOutputPath" not exposed in props
706+
jestBuildOutputPath: buildOutputPath,
707+
});
708+
countResources(stack, "AWS::SQS::Queue", 1);
709+
hasResource(stack, "AWS::SQS::Queue", {
710+
DelaySeconds: 30,
711+
});
712+
});
713+
696714
test("constructor: cfCachePolicies props default", async () => {
697715
const stack = new Stack(new App(), "stack");
698716
new NextjsSite(stack, "Site", {

www/docs/constructs/NextjsSite.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,9 @@ Note that the certificate needs be created in the `us-east-1`(N. Virginia) regio
237237

238238
Also note that you can also migrate externally hosted domains to Route 53 by [following this guide](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/MigratingDNS.html).
239239

240-
### Configuring the Edge Functions
240+
### Configuring the Lambda Functions
241241

242-
Configure the internally created CDK [`Lambda@Edge Function`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudfront.experimental.EdgeFunction.html) instance.
242+
Configure the internally created CDK [`Lambda Function`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html) instance.
243243

244244
```js {3-7}
245245
new NextjsSite(this, "Site", {
@@ -358,6 +358,12 @@ _Type_ : [`cdk.aws-cloudfront.Distribution`](https://docs.aws.amazon.com/cdk/api
358358

359359
The internally created CDK `Distribution` instance.
360360

361+
### sqsRegenerationQueue
362+
363+
_Type_ : [`cdk.aws-sqs.Queue`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_sqs.Queue.html)
364+
365+
The internally created CDK `Queue` instance.
366+
361367
## Methods
362368

363369
An instance of `NextjsSite` contains the following methods.
@@ -436,11 +442,17 @@ _Type_: [`NextjsSiteCachePolicyProps`](#nextjssitecachepolicyprops)
436442

437443
Pass in a `NextjsSiteCachePolicyProps` value to override the default CloudFront cache policies created internally.
438444

445+
### sqsRegenerationQueue?
446+
447+
_Type_: [`cdk.aws-sqs.QueueProps`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_sqs.QueueProps.html)
448+
449+
Pass in a `cdk.aws-sqs.QueueProps` value to override the default settings this construct uses to create the CDK `Queue` internally.
450+
439451
### defaultFunctionProps?
440452

441453
_Type_: [`NextjsSiteFunctionProps`](#nextjssitefunctionprops), _defaults to_ `{}`
442454

443-
The default function props to be applied to all the Lambda@Edge functions created by this construct.
455+
The default function props to be applied to all the Lambda Functions created by this construct.
444456

445457
### disablePlaceholder?
446458

@@ -494,13 +506,13 @@ Set this option if the domain is not hosted on Amazon Route 53.
494506

495507
_Type_ : `number`, _defaults to 10_
496508

497-
Lambda@Edge function execution timeout in seconds.
509+
Lambda function execution timeout in seconds.
498510

499511
### memorySize?
500512

501513
_Type_ : `number`, _defaults to 1024_
502514

503-
The amount of memory in MB allocated to this Lambda@Edge function.
515+
The amount of memory in MB allocated to this Lambda function.
504516

505517
### permissions?
506518

0 commit comments

Comments
 (0)