-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Tags not applied in aspects in 1.45 #8536
Comments
Hi! Tags are implemented using aspects, so in the code you pasted, which uses aspects to tag constructs you are actually applying an aspect via an aspect, this was never truly supported in the CDK and would only work in very specific cases, depending on the order in which the construct tree was built. While we investigate this, it seems like you are trying to tag all constructs which are defined inside a stack? If so, could you instead add the tag to the stacks? Let me know if I missed something in your use case. |
What I am trying to achieve is to tag all resources in the application, without having to change the stacks or maintain an extra statement per stack. The tag value also includes the stack name, or otherwise I could have worked around this by Maybe there should be some error if an aspect is applied while already applying a aspect? For my use case I can probably solve this by creating a custom Tag implementation. |
I've worked around this by avoiding the nested aspects (by using |
Im glad to hear you found a workaround, Im closing this in favor of #8639 |
### Updated PR Since we introduced [`stages`](#8423) which had the unintended side effect of the CDK not supporting adding an Aspect via another Aspect, we have not seen any issues reported beside #8536, that was resolved without requiring this capability. Given that, and the fact this features has many sharp edges we decided to leave it unsupported, and add a warning in the meantime. ----------- Following up on #8536 If an aspect is added via another aspect, the inner aspect will not be invoked. Take for example this code: ```typescript const app = new cdk.App(); app.node.applyAspect({ visit(construct: cdk.IConstruct) { construct.node.applyAspect({ visit(construct: cdk.IConstruct) { console.info("Invoking aspect on construct: " + construct.node.id); // This will not be called } }) } }); ``` Since aspects are added only on the top level node, if an aspect is added while `InvokeAspects` is called on that node, it will be ignored since it will not be added to list of aspects to invoke (`allAspectsHere` in the bellow code): ```typescript function invokeAspects(root: IConstruct) { recurse(root, []); function recurse(construct: IConstruct, inheritedAspects: constructs.IAspect[]) { // hackery to be able to access some private members with strong types (yack!) const node: NodeWithAspectPrivatesHangingOut = construct.node._actualNode as any; const allAspectsHere = [...inheritedAspects ?? [], ...node._aspects]; for (const aspect of allAspectsHere) { if (node.invokedAspects.includes(aspect)) { continue; } aspect.visit(construct); <-- an aspect that was added here will not be added to `allAspectsHere` and will be ignored node.invokedAspects.push(aspect); } for (const child of construct.node.children) { if (!Stage.isStage(child)) { recurse(child, allAspectsHere); } } } } ``` Assuming this is not something we want to support**, we can detect it by comparing the size of `node._aspects` before and after the call to `aspect.visit`, and emit a warning if there has been a change. Note that while the aspect will not be invoked it will be added to every child construct during the recursive visit. Emitting a warning for each child construct will result in a noisy console, to prevent this I have added a flag that will only allow adding **one warning per application**, given this limitation I'm not sure there is a lot of value in adding the warning, thoughts? If we decide to add it I will add tests. (** theoretically we could support it by adding the aspects to `allAspectsHere` during the loop, but this will require a non trivial implementation in order to avoid infinite recursion) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
### Updated PR Since we introduced [`stages`](#8423) which had the unintended side effect of the CDK not supporting adding an Aspect via another Aspect, we have not seen any issues reported beside #8536, that was resolved without requiring this capability. Given that, and the fact this features has many sharp edges we decided to leave it unsupported, and add a warning in the meantime. ----------- Following up on #8536 If an aspect is added via another aspect, the inner aspect will not be invoked. Take for example this code: ```typescript const app = new cdk.App(); app.node.applyAspect({ visit(construct: cdk.IConstruct) { construct.node.applyAspect({ visit(construct: cdk.IConstruct) { console.info("Invoking aspect on construct: " + construct.node.id); // This will not be called } }) } }); ``` Since aspects are added only on the top level node, if an aspect is added while `InvokeAspects` is called on that node, it will be ignored since it will not be added to list of aspects to invoke (`allAspectsHere` in the bellow code): ```typescript function invokeAspects(root: IConstruct) { recurse(root, []); function recurse(construct: IConstruct, inheritedAspects: constructs.IAspect[]) { // hackery to be able to access some private members with strong types (yack!) const node: NodeWithAspectPrivatesHangingOut = construct.node._actualNode as any; const allAspectsHere = [...inheritedAspects ?? [], ...node._aspects]; for (const aspect of allAspectsHere) { if (node.invokedAspects.includes(aspect)) { continue; } aspect.visit(construct); <-- an aspect that was added here will not be added to `allAspectsHere` and will be ignored node.invokedAspects.push(aspect); } for (const child of construct.node.children) { if (!Stage.isStage(child)) { recurse(child, allAspectsHere); } } } } ``` Assuming this is not something we want to support**, we can detect it by comparing the size of `node._aspects` before and after the call to `aspect.visit`, and emit a warning if there has been a change. Note that while the aspect will not be invoked it will be added to every child construct during the recursive visit. Emitting a warning for each child construct will result in a noisy console, to prevent this I have added a flag that will only allow adding **one warning per application**, given this limitation I'm not sure there is a lot of value in adding the warning, thoughts? If we decide to add it I will add tests. (** theoretically we could support it by adding the aspects to `allAspectsHere` during the loop, but this will require a non trivial implementation in order to avoid infinite recursion) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
### Updated PR Since we introduced [`stages`](aws#8423) which had the unintended side effect of the CDK not supporting adding an Aspect via another Aspect, we have not seen any issues reported beside aws#8536, that was resolved without requiring this capability. Given that, and the fact this features has many sharp edges we decided to leave it unsupported, and add a warning in the meantime. ----------- Following up on aws#8536 If an aspect is added via another aspect, the inner aspect will not be invoked. Take for example this code: ```typescript const app = new cdk.App(); app.node.applyAspect({ visit(construct: cdk.IConstruct) { construct.node.applyAspect({ visit(construct: cdk.IConstruct) { console.info("Invoking aspect on construct: " + construct.node.id); // This will not be called } }) } }); ``` Since aspects are added only on the top level node, if an aspect is added while `InvokeAspects` is called on that node, it will be ignored since it will not be added to list of aspects to invoke (`allAspectsHere` in the bellow code): ```typescript function invokeAspects(root: IConstruct) { recurse(root, []); function recurse(construct: IConstruct, inheritedAspects: constructs.IAspect[]) { // hackery to be able to access some private members with strong types (yack!) const node: NodeWithAspectPrivatesHangingOut = construct.node._actualNode as any; const allAspectsHere = [...inheritedAspects ?? [], ...node._aspects]; for (const aspect of allAspectsHere) { if (node.invokedAspects.includes(aspect)) { continue; } aspect.visit(construct); <-- an aspect that was added here will not be added to `allAspectsHere` and will be ignored node.invokedAspects.push(aspect); } for (const child of construct.node.children) { if (!Stage.isStage(child)) { recurse(child, allAspectsHere); } } } } ``` Assuming this is not something we want to support**, we can detect it by comparing the size of `node._aspects` before and after the call to `aspect.visit`, and emit a warning if there has been a change. Note that while the aspect will not be invoked it will be added to every child construct during the recursive visit. Emitting a warning for each child construct will result in a noisy console, to prevent this I have added a flag that will only allow adding **one warning per application**, given this limitation I'm not sure there is a lot of value in adding the warning, thoughts? If we decide to add it I will add tests. (** theoretically we could support it by adding the aspects to `allAspectsHere` during the loop, but this will require a non trivial implementation in order to avoid infinite recursion) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
I have an aspect to add tags to all resources in the app.
It worked in 1.44, but in 1.45 tags are not added.
Reproduction Steps
No tag added. Full reproduction repo from sample-app: https://github.com/henrist/cdk-aspect-tag-issue - the commits shows it working in 1.44 before not producing tags in 1.45.
Error Log
No error seen. However, the log statement shown above is triggered, so the cdk.Tag.add is called.
Environment
Other
The same code worked fine in 1.44, but no tags are emitted in 1.45.
In our setup I have a helper to simplify this found at https://github.com/capralifecycle/liflig-cdk/blob/9032da75b67d4d5ffa1b518034cf3150091c398a/src/tags.ts
We commit snapshots of the templates in the Cloud Assembly, which led us to catch this during update to 1.45.
This is 🐛 Bug Report
The text was updated successfully, but these errors were encountered: