-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
(core): cdk synth
always synthesizes every stack
#6743
Comments
@Townsheriff Did you use the I'm working on a repro so I can dive deeper into the behaviour. I'm going to create an app with 2 stacks (both leveraging assets) and then try to synth and deploy one of them and also providing the |
@shivlaks I did not use the option, perhaps that is solution. I ended up adding env variable which I would use in ts file to determine which stack should be synthesised. |
@shivlaks Were you able to reproduce with the |
@jgondron apologies, I have not had a chance to follow up on this one. Can you describe your environment/setup at a high level? |
@shivlaks I have a multistack app with Our current work around is to add something like this to
Doing this protects it from throwing an exception, but still fails to deploy |
- Changed image processing pipeline to get manifest pipeline bucket names from other stacks instead of requiring them via context - Changed image processing to use the env config to get the rbsc bucket since that changes per env - Fixed an issue with the target stack names. We had changed them from `marble-image` to `marble-image-processing` but had missed updating the pipeline to use these names when deploying. - Fixed an issue with the code terminating too soon during synth, preventing cdk from seeing dependencies correctly. We need to find an alternative solution to the `if !fs.existsSync(props.lambdaCodePath); return` checks that still allow the code to continue, but still throws an error when that stack is deployed. In this specific case, cdk was not seeing the dependency between image processing and manifest pipeline because the manifest pipeline was exiting too soon due to the missing files. For now, I just moved these fs checks down a bit and forced the export/import to happen in the manifest pipeline. This is a pretty fragile solution, and it's not very intuitive what's happening when this occurs, so I'm going to look for a more general solution to this, but this fixes the immediate issue for now. See aws/aws-cdk#6743 for the original issue we were trying to prevent with these checks.
I am encountering the same issue. Synthesising or attempting to deploy a stack with the I've put a minimal reproduction together at https://github.com/dansalias/tmp-cdk-6743 |
In my case I have a repository with a number of services, each with their own build process (to compile lambdas) and CDK stack, managed through the same CDK app. When a given service is updated its build process is triggered, followed by deployment. The way the cdk is currently setup requires all services to be built even if just a single service is to be deployed. I'm happy to work on a PR for this but it would be useful to have some guidance. I imagine it would be a case of advancing this logic so that unspecified stacks aren't even synthesised in the first place. |
@ericzbeard @rix0rrr are we able to revisit this please? |
Any update on this? |
@shivlaks Any update on this? I think that be forced to build everything just to deploy one stack is really bad. |
What I've done so far, for those looking for a workaround, is to rely on if (!this.bundlingRequired) {
// We must skip undesired stacks to be able to deploy specific stacks.
// Refer to: https://github.com/aws/aws-cdk/issues/6743
console.info('Skipping ' + this.stackName);
return;
} This works because in case your stack is selected to be deployed |
I really like the possibility to simply deploy typescript lambdas with cdk. However, this issue is the only big pain I have with cdk. If I have to deploy one stack quickly (in a dev environment), I have to wait multiple times. We have mutiple step function with multiple lambdas each. Every step function is in one stack. If we only want to deploy one step function to test it, we always have to wait for all assets of all stacks to be bundled. If you made a mistake and want to deploy again, you have to wait again for everything to be bundled. Is there any workarround? Is there a best practice to design the stacks so this is not an issue? |
It seems like the proper solution is to just make separate CDK projects for each stack....or I guess switch back to Terraform. I can't believe this comment thread is still going with no resolution after 3 years. Its so frustrating, somehow AWS makes their active codebase on the tool they tell everyone to use feel like abandonware. In my case I have two stacks:
The build pipeline builds the lambda functions, outputs zip files. But since -e doesn't actually work, I can't deploy the pipeline stack without using one of the above hacks. |
Hot swapping |
cdk synth
always synthesizes every stack
The suggestion here: #28136 (comment) is the recommended best practice to avoid this issue. I will get our developer guide updated to reflect this. The core reason behind this recommendation is that
The errors complaining about non-existent assets are thrown during the execution of your CDK program, so the only way to prevent them is to prevent the CDK from executing that code. The best way to do that is to use some environment variables to prevent the execution of that stack code, as shown by @tmokmss. |
No, the best way would be for the CDK CLI to be smart enough to understand that
Btw, the "cdk deploy" command already understands (somewhere at a later stage after |
Actually, I don't see why the use case is so difficult to understand. The command speaks for itself. When an engineer runs I don't want to synthesize the whole app and throw away all stacks, but StackB. If that was the case, a better signature for the command would have been |
I understand the use case; it makes sense that The problem is that synthesis operates on the entire CDK Synthesis, as a consequence of its current design, cannot be made to operate on individual stacks in the way you have described. I have thought of the following modifications to the design of synthesis that may support this use case, but I don't believe any of them solve more problems than they create. As far as I am aware, there is no way to tell node (or all the other language runtimes we support) to selectively ignore constructor calls to classes that do not match a certain glob string. We can't catch and ignore errors thrown from this process, because any errors in that process will terminate it. The best we can do is restart it, and that will just rethrow the same error. Maybe we can workaround this by loading and executing that code at runtime (not sure if this is really possible), but even if we do that, it's not really selectively synthesizing; it's just ignoring certain errors. Maybe we can provide a custom node runtime that allows us to pass this globstring to the process and selectively ignore constructor calls, but this would need to be very carefully designed and maintenance tradeoffs would need to be considered; I don't expect it would be worth it. Maybe we can modify the jsii compiler to inject special code into stack constructors to make it ignore certain stack calls, but it's not clear how viable or possible this is. A less generalized solution, but one that might be more viable, is to vend different I don't like any of these options, because they violate the core premise of Please let me know if there are implementation paths that I have missed. Contributions are always welcome. |
Ultimately the reason I'd like to synthesise only one stack is to save time. More generally, it would be great if it worked like build systems, which are smart enough to only build what has changed. Why should I wait to resynthesise the whole app when my Let's say I have a dependency chain of stacks A → B → C (i.e. A depends on B, and B depends on C). Intuitively, when I run @comcalvi For the sake of synthesising one stack, is it necessary to avoid construction of the other stack classes? Can it still construct the stacks, but when it comes to synthesis, re-use what's in |
This issue has received a significant amount of attention so we are automatically upgrading its priority. A member of the community will see the re-prioritization and provide an update on the issue. |
This issue has been open for 4 years, it does not look like a core change would be made anytime soon. If you need to DIY it, you can do so without an extra context variable: You can get the stack/bundle specifier and then conditionally (using if statements) create the stacks within your code. Example: If I do this CDK command:
Then you can find the stack identifier in the environment variable below, it will print: console.log(JSON.parse(process.env.CDK_CONTEXT_JSON || "{}")['aws:cdk:bundling-stacks']);
// Outputs: [ 'workloads-base-*' ] This can then be used to create Is it "hacky" and ugly, yes. But it's the only way I know of how to do it atm. |
@comcalvi a relatively low-hanging fruit type of solution to this problem, that combines the suggestion from the latest comment by @rehanvdm, might be the following: Since all Stacks that are part of a CDK app are forced to call This means that this super constructor has the opportunity to "analyze" which stacks the user wants synthesized (by parsing the In that way, that parent constructor can understand if the "current stack" needs synthesis or not, and if not - do an Does this sound like a feasible solution? Any blockers? |
❓ General Issue
I have multiple stacks in my project and want I deploy only one of them all other stack assets must be present in file tree or else I get
ENOENT: no such file or directory, stat...
.I did a little digging and figured:
a. cdk cli spawns process
ts-node /bin/script.ts
b. cdk cli does not pass stack name to aws-cdk, therefore I cannot know which should be synthesized
c. aws-cdk generates all cloudformation jsons for all stacks it can find and cdk cli picks the ones it needs
I think it would be smart to provide the name of stack and generate only provided one, it would be faster and would not require all assets to be present.
PS.
With aws-cli I'm referening to aws-cdk installed globally and with aws-cdk I refer to project dependency.
The Question
Environment
Other information
The text was updated successfully, but these errors were encountered: