-
-
Notifications
You must be signed in to change notification settings - Fork 457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CDK Construct #878
CDK Construct #878
Conversation
Codecov Report
@@ Coverage Diff @@
## master #878 +/- ##
==========================================
+ Coverage 80.73% 81.31% +0.57%
==========================================
Files 64 68 +4
Lines 2403 2488 +85
Branches 561 591 +30
==========================================
+ Hits 1940 2023 +83
+ Misses 399 398 -1
- Partials 64 67 +3
Continue to review full report at Codecov.
|
This is awesome @kirkness 🙌 Actually I think this aligns well with what @dphang outlined in #777. There is the question of CDK vs CDK for Terraform, but I don't see why we shouldn't make a start with plain CDK if you've done all the hard work already. I will try to test out this branch over the weekend and will feedback.
We do need more contributors and I can add you to the repo's maintainers if that's something you're interested in 🙂 CC'ing @dphang for any thoughts on this. |
destinationKeyPrefix: staticAsset, | ||
distributionPaths: ["/*"], | ||
sources: [s3Deploy.Source.asset(assetPath)], | ||
cacheControl: [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Static Pages would need different cache control here: public, max-age=0, s-maxage=2678400, must-revalidate
.
And also in the latest 1.19 alpha, we are now versioning pages so only the last two deployments are kept to save S3 space.
See the code here:
const deleteOldStaticAssets = async ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will have a look into how static pages are being versioned, but I presume this means no invalidation is required for these either which is nice! This is something I wanted to revisit as it's currently creating an invalidation on all resources every deploy which is unnecessary given everything is versioned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And also in the latest 1.19 alpha, we are now versioning pages so only the last two deployments are kept to save S3 space.
I believe this is actually handled by CDK itself as it automatically 'syncs' source assets, deleting ones that no longer exist. I'm assuming the reason you are keeping the last 2 deployments is for safety and thus this behavior is not needed for the construct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -0,0 +1 @@ | |||
exports.handler = async () => ({ statusCode: 200 }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better readability of all these added JS/JSON files, could you please format these test files using prettier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in ea6cc16
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although, prettier has not updated __tests__/fixtures/next-boilerplate/default-lambda/index.js
...
@kirkness thanks a lot for this! Yea, we have been talking about adding CDK for a while now but just haven't had resources. So this is a good first step! We are also trying to upgrade to Serverless Components GA, if you are interested as mentioned it might go hand-in-hand with this as we are trying to make deployments more seamless in the near future (+ there is significant financial sponsorship (like $1k+) from Serverless Framework for doing so, which we would be happy to split based on resourcing). Do let @danielcondemarin know and we can add you to the Slack too. |
Great news, would be awesome to join you on Slack to kick this off! My email is just my first name (Henry) + my company domain (planes.studio). In the meantime, I'll revert this PR to a draft and flesh out a plan of attack with some of the additional work that's needed to go into it. |
bucketName, | ||
credentials: credentials | ||
}); | ||
const getAssetDirectoryFileCachePolicies = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've taken all the logic from uploadStaticAssetsFromBuild
that determines the cache-control for each file in /assets
and refactored it to be agnostic to the deployment mechanism. This file is imported into the CDK construct now, whilst also used below in uploadStaticAssetsFromBuild
. I think we could do with a grander refactor of this form that removes the deployment code from the synthesis.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This didn't make sense to use in the end as the data structure required to work with the constructs didn't fit this output enough to make it worth it. Happy to revert the changes to this module if you think its needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be ok to keep it.
@@ -1,3 +0,0 @@ | |||
import { Item } from "klaw"; | |||
|
|||
export default (fileItem: Item): boolean => !fileItem.stats.isDirectory(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed anymore as we get fast-glob
to only read files.
Thanks for working on this @kirkness! One thing to think about is, have you considered the potential order of events that may be needed before the frontend assets are deployed? One think I've come up against when using CDK to deploy frontend assets is that there is currently no way that I saw to have "backend" infra deploy first and to pass API endpoints, outputs, into the frontend construct so they can be bundled into the frontend assets. Have you found away around this? Is there anything I might be able to help out with in these efforts? |
👍, sure I think I know what you mean, as you might:
I think at the very least, if the bundling was done within the construct, then you'd be able to pass in non-tokenized values as env vars, all inline with your CDK code. |
This would be SUPER ideal. Any work towards this working now? |
I think all that would be needed is to set up Asset Bundeling, which would allow running the Might have a look at a POC now. Watch this space. 👍 |
Parking this now, the CDK asset bundling process starts after the CDK constructs are created. At the point when we create the Next.js construct we need the next.js app to be bundled, this is because the infrastructure bases itself on the shape of the bundled output. So similar in part to the issue you outlined with env variables (that this was trying to resolve). On top of this, the env vars passed into the asset bundling process are not resolved, and so you end up with tokenized values. More research needed - an easy way would be just to bundle without the use of the asset bundling construct, although keen to find a best-practice approach! |
Cheers @dphang - just ran through those changes. Is i18n a blocker/substantial change? Will put in follow up PR if all good with you? |
I think it should probably work as is since it was just modifying the output HTML/JSON files to Also, looks like some of the new tests in the CI build is failing now. Thanks for this! |
Nice, sounds like it'll work then as each directory of the output is uploaded to s3/lambda as the sls component does. Ive updated the test snapshots so that they pass. |
…also allow users to pass custom invalidationPaths
Thanks, I ran e2e tests here: https://github.com/serverless-nextjs/serverless-next.js/actions/runs/565470296 |
@kirkness looks like everything is good. LMK if ready to merge? |
Great work! I am looking towards this for some time. There are some example repo for me take a look? Tried to add to a codebase and even started from scratch but cdk deploy only generates a new config, cdk.out remains empty and the command stalled. When I added the builder debug flag true it just showme the log for the application starting. Just a barebones example besides the code provided so far in the docs would be great, Because of my limits I was not able to use it 😓 Thanks in advance! |
Hey @ibrahimcesar - sounds odd, I don't suppose you could push your example up to a repo (just the one you did from scratch)? |
Sure @kirkness ! Thanks! |
Cheers @ibrahimcesar, I've updated the docs in this PR, it looks like you may have a couple of other unrelated issues in that repo, but hopefully they'll be obvious when it actually starts to build. |
Thanks @kirkness , Yes, there are some configs missing, but "life finds a way" One hookie mistake I made, and l'll leave here as reference, is that I changed my
Since I saw it was accessing the files at "build", but just leave the default build, or will fail because it will lookup in Updated my simple repo with a working version! Thanks a lot! |
Wow, greet work @kirkness ! Now, my specific interest is in the CDK construct alone.
|
(FYI for others: Not sure if it's my fault, but I tried to play around with this CDK Construct and always hit a Update: So apparently it is a config problem on my side, but not related to role permissions, but the account wide "Block Public Access settings" in S3. It looks like those settings would overrule anything I'd configure on the bucket, so I need to change them.) |
@kirkness When using the CDK construct outside of serverless components. what is the best way to organize your I thought it would just be as simple as building in completely separate directory and just copying in the build files, but the CDK build process needed all the next apps deps and now its saying it needs the src pages directory too. Not sure if its possible or the best way to keep some separation between the CDK stack files and the nextjs app its deploying? I'm trying to run things in separate directories and leverage the However it err's our with... next.config.js module.exports = {
target: "serverless",
} /bin/cdk-nextjs.ts ...
const nextConfigDir = path.join(__dirname, '../dvb-next');
const outputDir = path.join(nextConfigDir, ".serverless_nextjs");
const builder = new Builder(nextConfigDir, outputDir,
{
cmd: './node_modules/.bin/next',
cwd: '../dvb-next',
env: {},
args: ['build']
});
... UPDATE - ...
const nextConfigDir = path.join(__dirname, '../../dvb-next');
const outputDir = path.join(nextConfigDir, ".serverless_nextjs");
const builder = new Builder(nextConfigDir, outputDir,
{
cmd: './node_modules/.bin/next',
cwd: nextConfigDir,
env: {},
args: ['build']
});
... |
Glad you got it working @iDVB, feel free to create issues if you have any other problems! |
Curious, is there a supported/recommended way to deploy a NextJS app with CDK but without Serverless? |
@revmischa What do you mean by supported? Like a package? Because you only need to build your own constructor but there's a lot for React applications as whole in community. CDK is a general purpose tool so you can create an EC2 Instance and run NextJS inside or use ECS if your application is on Docker or even Fargate, but this service is considered serverless. But CDK gives you access to create any kind of infrastructure on AWS so you can do as you want. |
Yeah ideally deploying it using the https://docs.aws.amazon.com/cdk/api/latest/docs/aws-lambda-nodejs-readme.html construct. Just not sure on what to put in my handler. |
@revmischa I don't think you gonna achieve what you want with this constructor in particular. It is serverless and is a Lambda. The architecture is a bit different, I don't think this is the right forum. You can ask me directly and I can help you. |
This may be wildly out of scope for this project at the moment(⁉️ ) as per #777. I've been using CDK + Next.js with the sls-next
Builder
for around a year now on a couple of different projects. To make this possible I've evolved this CDK Construct which is by now fairly well battle-tested; all the while trying to keep it in line with the way that theserverless-component
works. I'm quite keen on open-sourcing it and think it makes the most sense to exist in this project. Keen to know whether this is something that is of interest including in the project at the moment?Todo:
Future possibilities:
Side-note: I'm also keen on getting more involved with the maintenance and support for this project if there still a need (especially helping on the work outlined in #777).