Skip to content
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: incorrect asset bundling skip for assets in stacks inside stages inside stacks #21925

Closed
plumdog opened this issue Sep 6, 2022 · 9 comments
Assignees
Labels
@aws-cdk/core Related to core CDK functionality bug This issue is a bug. effort/medium Medium work item – several days of effort p1

Comments

@plumdog
Copy link
Contributor

plumdog commented Sep 6, 2022

Describe the bug

Eg when you have:

  • PipelineStack
    • DeploymentStage
      • DeploymentStack
        • SomeLambda

If I try to deploy just the DeploymentStack with npm run -- cdk deploy -e pipeline-stack/deployment-stage/deployment-stack, the asset for SomeLambda is not bundled. Instead, I just get the whole repo, and Lambda complains about the zip being too big.

I think this might be because of this line here: https://github.com/aws/aws-cdk/blob/v1-main/packages/@aws-cdk/core/lib/stack.ts#L1179

Perhaps that .replace should instead act on the last occurrence in the string, not the first. This is half right. this.stackName is deployment-stage-deployment-stack, but bundlingStacks from cxapi.BUNDLING_STACKS is pipeline-stack/deployment-stage/deployment-stack. So to get the correct behaviour need to munge pattern as follows:

  • replace the last / with a -
  • then remove everything up-to-and-including any remaining /

But this feels - in general - unsafe. Why are cxapi.BUNDLING_STACKS and this.stackName in different formats and what is a valid way of comparing them?

The above would match with some crude debugging I bodged into my project where I encountered this, and with the comment there "bundlingStacks is of the form Stage/Stack, convert it to Stage-Stack before comparing to stack name": if I override bundlingRequired in my stack and print out what this.node.tryGetContext(cxapi.BUNDLING_STACKS) ?? ['*'] is, I get ['pipeline-stack/deployment-stage/deployment-stack'], but this.stackName is 'deployment-stage-deployment-stack'.

So when the first / is replaced and the minimatch comparison occurs, the match fails, because it was the first / that was replaced. If it was the last, then it would match. (false, see above)

Expected Behavior

The asset for the stack I am deployed to be bundled.

Current Behavior

The project root is zipped as the asset.

Reproduction Steps

I'm in the process of trying to write a failing test, but am fighting buildup atm.

The test I'm trying to write looks just like the test added in cda6601 but with an extra layer of nesting, like Stack1/Stage/Stack2.

Possible Solution

In Stack.bundlingRequired, replace the last / in pattern, not the first.

Additional Information/Context

I think this is related to #15346

CDK CLI Version

2.35.0

Framework Version

No response

Node.js Version

16

OS

Linux

Language

Typescript

Language Version

No response

Other information

My workaround is to put:

public override get bundlingRequired() {
    return true;
}

in the Stack that contains the asset. This results in the expected behaviour.

@plumdog plumdog added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Sep 6, 2022
@github-actions github-actions bot added the @aws-cdk/core Related to core CDK functionality label Sep 6, 2022
@plumdog plumdog changed the title core: incorrect asset bundling skip for assets in stacks inside stages core: incorrect asset bundling skip for assets in stacks inside stages inside stacks Sep 6, 2022
@dragonlobster
Copy link

i have the same problem how to fix this?

@plumdog
Copy link
Contributor Author

plumdog commented Sep 6, 2022

@dragonlobster

I found that putting

public override get bundlingRequired() {
    return true;
}

in the stack class that directly contains the Lambda resulted in the correct behaviour, though will mean bundling sometimes happens unnecessarily.

@peterwoodworth
Copy link
Contributor

Could you clarify what error message you're getting (it's an error on deploy that the zipfile is too big for the lambda?), plus could you share reproduction steps (are you using just a lambda.Function?)? This pattern (stack with assets inside stage inside stack) is common and I've never come across any issues before - checking my cdk.out directory seems to give me about what I'm expecting with a directory just for the stage, and inside that directory there's a stack template and an asset just for the lambda

@peterwoodworth peterwoodworth added p1 response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed needs-triage This issue or PR still needs to be triaged. labels Sep 7, 2022
@plumdog
Copy link
Contributor Author

plumdog commented Sep 7, 2022

@peterwoodworth the behaviour only occurs when CDK is trying to work out which stacks need bundling and which don't, which I think is only when deploying with the -e switch to select a specific stack. So I think it requires all of the following to occur at once:

  • At least 3 layers of stacks or stages
  • A construct in such a stack that requires bundling. Certainly NodejsFunction is one of these, but I imagine there are others.
  • Only a subset of stacks are being acted on. Eg, -e is used to deploy such a stack.

When those three things occur:

Thinking about it further, I think it will also fail in the 2 layers case (so just Stage -> Stack -> NodejsFunction) if the stack's name is not the default.

I'll try to provide a way of replicating or a failing test.

@peterwoodworth
Copy link
Contributor

Thanks for the further explanation, it's a big help 🙂

@peterwoodworth peterwoodworth added the effort/medium Medium work item – several days of effort label Sep 7, 2022
@plumdog
Copy link
Contributor Author

plumdog commented Sep 7, 2022

Extra realisation that I'll check when I can: I think the cause is that cxapi.BUNDLING_STACKS refers to stacks by their path within the CDK App, but the comparison is with this.stackName.

These just happen to often be the same. A stack name defaults to the id, which is also the path when there's no stages. And a stack in a stage defaults to stage-stack, which is why the .replace sometimes works.

Assuming I'm on the right track, I think I can write a few failing tests, and I think the fix will be to compare with the stack's logical path instead of this.stackName.

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Sep 8, 2022
@kristiandreheraxis
Copy link

Is there any progress on this? Not being able to use the --exclusively flag is quite annoying when working on a project with many stacks.

@TheRealAmazonKendra
Copy link
Contributor

Looks like the fix for this has been merged. Closing.

@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/core Related to core CDK functionality bug This issue is a bug. effort/medium Medium work item – several days of effort p1
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants