I've deployed a NextJS site in production but my a...
# help
y
I've deployed a NextJS site in production but my aws account has hit a limitation with custom cache policies. It seems you are only limited to 20 per AWS account and this doesn't appear to be a quota that can be increased. Given that each Nextjs site requires 3 custom cache policies I'm limited to only 5 concurrent preview stacks / branches. Our immediate solution was to limit our workflow to checking out dedicated preview branches / stacks. Another solution that I'll most likely implement will be to override the cache policies to be shared across all stacks. These cache policies tend to stay static, however this will cause our stacks to fail to be cleaned up after we merge our PRs (there's a shared dependency now across stacks). Has anyone encountered this issue?
t
@Frank I was giving this some thought and I wonder if this is a situation that forces us to deploy a "sst support stack" once per app Seems like we need to create the cache policy once in it and import it by default In the NextJSConstruct Not sure if there's a better way to do this
f
good new guys… Derek had a similar issue, and he submitted a PR for re-using cache policies https://github.com/serverless-stack/serverless-stack/pull/900
Essentially you create the cache policies manually, and pass them into all the NextjsSite instances.
I’m going to merge this soon!
y
oooh this is is great! Would this ignore the shared policies during a teardown (in the case of previews?)
t
Ah totally forgot the strategy of manually creating things 😄
Yeah teardowns won't touch the shared policy
f
Hey @Yousef, just pushed this in v0.49.2. Here’s an example of how to reuse CF cache policies https://docs.serverless-stack.com/constructs/NextjsSite#reusing-cloudfront-cache-policies
y
Amazing, will give this ago. Thanks for the quick turnaround @Frank 🙏
Update: attempted to re-use cache policies across PR branch stages but rec'd the following error while building against a pre-existing shared cache policy
34259 | CREATE_FAILED | AWS:CloudFront:CachePolicy | StaticCache185A1D0E - Internal error reported from downstream service during operation 'AWS:CloudFront:CachePolicy'.
134300 | CREATE_FAILED | AWS:CloudFormation:CustomResource | NextSiteCertificateCertificateRequestorResource7D52AF43 - Resource creation cancelled
134307 | CREATE_FAILED | AWS:Lambda:Function | NextSiteS3Handler2C74DCB2 - Resource creation cancelled
134314 | CREATE_FAILED | AWS:CloudFront:CachePolicy | ImageCache1A294B32 - Internal error reported from downstream service during operation 'AWS:CloudFront:CachePolicy'.
134317 | CREATE_FAILED | AWS:CloudFront:CachePolicy | LambdaCache0E53A4C7 - Internal error reported from downstream service during operation 'AWS:CloudFront:CachePolicy'.
Was able to resolve this using cloudfront.CachePolify.fromId
f
Hey @Yousef, has this worked for other PR stages before, and started happening now?
y
This was my initial attempt to test the new cFCachePolicy feature you merged in. So no, no previous attempts have been made
f
Oh I see. Just to clarify, so you are creating the cache policies for ur main stage, and then importing them in the PR stages?
y
well i did create a cache policy in my main stage but when i attempted to deploy a new stage it failed. i then proceeded to reference those policies from the main stage in a dev stage. once the dev stage deployed i merged those references in my main stage. So in effect theres no stage that creates the cache policies anymore. They all assume that it already exists
f
Oh I see… I think all stages importing the policies make sense, otherwise you’d run over 20 policies per account limit really quickly
A clean setup for this would be to have 1 stack that creates the policies only if it’s “dev” and “prod” stages:
Copy code
// CachePolicyStack.js
if (scope.stage === "dev" || scope.stage === "prod") {
  this.staticPolicy = new cf.CachePolicy();
  this.imagePolicy = new cf.CachePolicy();
  this.lambdaPolicy = new cf.CachePolicy();
}
else {
  this.staticPolicy = cf.CachePolicy.fromId("dev-static-policy-id");
  this.imagePolicy = cf.CachePolicy.fromId("dev-image-policy-id");
  this.lambdaPolicy = cf.CachePolicy.fromId("dev-lambda-policy-id");
}
And then pass these policies to the Nextjs stack to use.
Let me know if this makes sense.
y
Yep I figured this out after my trial and error this morning. I see that create isn't necessarily an upsert unique to the cache policy name