-
Notifications
You must be signed in to change notification settings - Fork 5.7k
WIP: Add high resource count support #3441
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
Conversation
const stackResource = _.cloneDeep(stackResourceTemplate); | ||
|
||
const stackNumber = index + 1; | ||
const resourceLogicalId = `NestedStack${stackNumber}`; |
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 should probably use provider.naming
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.
Good catch! Yep 100% agree...
This is mostly off the top of my head since I was setting out to work on this very same problem (as a plugin), from a design perspective maybe this could start by considering resources of known types, because then you can manage how much knowledge you have to have about the stack; for example CloudWatch::Metric objects are our most frequent resource right now, and so moving them to a separate stack can be done easily by understanding the points in the object structure that reference resources that will be downstream. |
1e3fe65
to
30bab6e
Compare
f4825ce
to
0a8161c
Compare
.then(this.generateStacks) | ||
.then(this.uploadStackFiles) | ||
.then(this.updateCompiledCloudFormationTemplate) | ||
.then(this.writeStacksToDisk); |
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.
worth doing this before the upload so that the can be seen for debug?
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 the new package/deploy semantics, it should be done in the deployment step, not the package step. Otherwise the deploy command would have to have too much knowledge about the stack splitting itself.
This has to be refactored anyway as soon as the new commands are released to hook the new command hooks.
Imo this should be discussed at a later time.
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.
Thanks for the feedback @dougmoscrop and @HyperBrain
Right now it 10000 's implemented this way so that we have all the URLs (e.g. to the function zips) in place.
Yes, this definitely needs an update once the new package and deploy support is in place.
This naive implementation splits the stack at all X resources.
0a8161c
to
cfc1687
Compare
@@ -0,0 +1,129 @@ | |||
'use strict'; |
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.
Why not some existing npm module?
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.
Good question. We tried existing ones, but both were not able to compute distinct clusters (here's one commit where we tried one --> f8d2935).
This code is able to compute non-overlapping clusters.
|
||
const stacks = []; | ||
|
||
// TODO update so that no stack splitting is done at all if not enough resources are present? |
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.
yes please! No need to complicate simple services which most of our users have.
Pretty cool @pmuens ... I think you'll need to make some changes to accommodate the recent changes in packaging/deployment. Best guess, most of the logic would be in the package plugin. |
I think there's a lot of contention as to how this should be implemented;
maybe focus on exposing an API to facilitate it and do this in a plugin?
…On Tue, Apr 18, 2017, 9:25 AM Eslam λ Hefnawy ***@***.***> wrote:
Pretty cool @pmuens <https://github.com/pmuens> ... I think you'll need
to make some changes to accommodate the recent changes in
packaging/deployment. Best guess, most of the logic would be in the package
plugin.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3441 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAjzFBghuOnZy6m1JPeGhKTGz8DaDBLOks5rxLmtgaJpZM4Mxs2r>
.
|
@eahefnawy I'm not sure if I agree with the package plugin as the container of the logics. It would be much easier to have it at the deploy plugin (somewhere before the uploadArtifacts event). Then the artifacts transferred from package to deploy would contain the original (non-split) CF template, and the deploy step would split them into the different stacks - imo stack splitting is a deployment feature not a package/build feature. |
@eahefnawy @HyperBrain thanks for the update on how to resolve the conflicts. I agree with @dougmoscrop that this might be better off in a separate plugin. The way we've planned and implemented it here won't work since everything is so dependent on each other that it will be super complicated to separate all the resources into separete, nested stacks. Furthermore there's #3475 which could be used to solve the problems this PRs tries to solve. @dougmoscrop do you have any idea how this should be implemented as a plugin? |
So I have an idea how I might implement such a plugin, which is I am going to try to move functions to their own individual stacks, and then move known resource types to those stacks (DLQ, CloudWatch items, etc.) and then figure out how to parameterize those sub-stacks (e.g. detect any Ref type values and make them stack parameters). I'm a bit behind on serverless developments, but the separate package vs. deploy step, that does not include the CF template right? So CF templates are still generated on deploy? |
@dougmoscrop The compiled (finalized) CF template is available on deploy time as Typically the deploy phase would be the target for any split operations done by a plugin. With the new lifecycle approach there are a bunch of new hookable events, that should perfectly fit for the plugin. There should be no further hooks than the 2 needed. |
@dougmoscrop thanks for jumping in and providing a possible solution / proposal for a plugin 👍 @HyperBrain thanks for more clarifications around the new We've discussed this PR yesterday and came to the conclusion that it's way too complex (and nearly impossible) to cluster the whole CloudFormation template with all its dependencies into separate nested stacks. After having some feedback in #3411 it seems like using Furthermore it looks like users want to have control over this process rather than having Serverless do its thing automagically. We've started a WIP PR for native This feature can be used to split stacks into separate units of deployment. Anyway we'd really love to have a plugin which approaches an automatic stack splitting. So it would be awesome if you could keep us posted on your process about this @dougmoscrop We'd be happy to promote this plugin as the go-to solution for this specific problem. I'll close this PR for now since we won't work on it anymore (at least for now). @dougmoscrop let us know if we can help you with the plugin development! |
Another update. We've tackled the problem again and are now working on a solution in #3504. The implementation is based on @dougmoscrop idea to create nested stacks based on functions and their dependants. |
Note: This is the first naive iteration. It's not 100% working right now and a better splitting algorithm (e.g. based on resource groups) is needed! Furthermore it's a WIP. The deployment fails because of unresolved refs etc.
Todos
Refs
etc.npm shrinkwrap
(currently fails on my machine)provider.naming
to centralize resource naming (e.g. nested stack resource logical ids)What did you implement:
Closes #3411
Add automatic stack splitting when service contains a high number of resources.
How did you implement it:
Serverless will check the compiled CloudFormation template before deploying to AWS. It will split the stack up into nested stacks if the resource count is above X resources.
After that it will upload the nested stack templates to the S3 Bucket and update the compiled CloudFormation template which is in memory. This makes this whole change encapsulated and backwards compatible.
The user has to specifically opt-in for this feature via the
useStackSplitting: true
config.How can we verify it:
Create a service which looks like the following:
Run
serverless deploy --noDeploy
and look into the.serverless
directory to see all the resources.Or run
serverless deploy
to deploy the stack.Is this ready for review?: NO
Is it a breaking change?: NO
/cc @brianneisler @eahefnawy @dougmoscrop