-
Notifications
You must be signed in to change notification settings - Fork 4.3k
fix(tags): excludeResourceTypes does not work for tags applied at stack level (under feature flag) #31443
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
Stacks are considered taggable, and so `Tags.of(this).add('key',
'value')` used to add tags to Stacks in scope. Usually this happens if
`this` is an instance of `Stack`, which it commonly is in user code.
Since `Tags.of(...)` walks the construct tree, it will add tags to the
stack *and* to all the resources in the stack. Then, come deploy time,
CloudFormation will also try and apply all the stack tags to the
resources again. This is silly and unnecessary.
In #28017, someone tries to use a CloudFormation intrisinc in a tag
applied using `Tags.of(this)`; that will work for resources as the tags
are rendered into the template, but it will not work for the stack
tags as those are passed via an API call, and intrinsics don't work
there.
IN THIS CHANGE
The *correct* solution to tagging all resources with an intrinsic
would be to tag each of them individually, as tagging a Stack
with an intrinsic is not possible. That's a poor user experience.
Resolve both the silly duplicate work as well as the "tagging with
an intrinsic" use case as follows:
- Stacks no longer participate in the hierarchical `Tags.of(...)`
tagging.
- Instead, only tags explicitly applied at the stack level (using
the `tags` constructor property) are renderd as stack tags.
This requires a user to make a conscious decision between resource-level
and stack-level tagging: either apply tags to the stack, which will
apply it to all resources; or apply tags to (groups of) resources inside
the template.
aws-cdk-automation
left a comment
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.
The pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.
A comment requesting an exemption should contain the text Exemption Request. Additionally, if clarification is needed add Clarification Request to a comment.
✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.
I think this makes a lot of sense and it's the right think to address the fundamental flaw. My concern is the implementation is using a feature flag and otherwise sticks to the very cool but also super vague We could instead take this as an opportunity to deprecate the current aspect (and maybe add a warning/error to catch the unsupported use case) and implement the new feature as |
I considered this and was a bit worried about it. Under the new behavior, I suppose we could deprecate |
|
There's two other options:
I agree; it seems the only time you don't want it is when that tag contains a Token, so dropping the unresolved tokens would be nice; is that too much behavior hidden from users though? I don't think the |
I think silently ignoring what the user asks for is not great behavior.
Exactly 😉 |
|
As I thought, this would be harder to close. So I split off the most important bit to another PR: #31457 |
|
@rix0rrr, then should we close this PR ? |
|
Comments on closed issues and PRs are hard for our team to see. |
| */ | ||
| public add(key: string, value: string, props: TagProps = {}) { | ||
| // Implicitly add `aws:cdk:stack` to the `excludeResourceTypes` array in modern behavior | ||
| if (this.explicitStackTags && !props.includeResourceTypes?.includes('aws:cdk:stack')) { |
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.
If props.includeResourceTypes?.includes('aws:cdk:stack') is true, is there still a point in having the aspect traverse the tree? Can't we call addStackTag() to the stack and stop?
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.
Fair point, but if the user wanted exactly that behavior they would just set the stack tags directly.
I'm including this as an easy way of restoring the old behavior locally, for those people who might want it (for whatever ill-conceived reason). I don't seriously think it will see big adoption because it shouldn't, but I'm hesitant to take it away alltogether as well.
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Stacks are considered taggable, and so
Tags.of(this).add('key', 'value')used to add tags to Stacks in scope. Usually this happens ifthisis an instance ofStack, which it commonly is in user code.Since
Tags.of(...)walks the construct tree, it will add tags to the stack and to all the resources in the stack. Then, come deploy time, CloudFormation will also try and apply all the stack tags to the resources again. This is both unnecessary, as well as leads to loss of control:excludeResourceTypesappears to not work, since it will lead to resources not being tagged in the template (good) but then the resources will still be tagged by CloudFormation because the stack itself is tagged (bad).Also, if the tags applied this way contain intrinsics, they will contain nonsense because they are applied in a context where CloudFormation expressions don't work.
In this change
There is way to prevent Stacks from being tagged, by including
aws:cdk:stackin the list ofexcludeResourceTypes(this is a fake resource type that Stack tags respect).Under a feature flag,
@aws-cdk/core:explicitStackTags, this is now the default behavior. That resource type will be excluded by default, unless it is listed in theincludeResourceTypeslist. However, doingincludeResourceTypesis still not desirable: stack tags should be applied directly on theStackobject if desired.This requires a user to make a conscious decision between resource-level and stack-level tagging: either apply tags to the stack, which will apply it to all resources but remove the ability to do
excludeResourceTypes; or apply tags to (groups of) resources inside the template.Another benefit is that for tags applied at the stack level, this will resolve the following issue: #15947, as resources "becoming" taggable all of a sudden will not affect the template anymore.
Closes #28017. Closes #33945. Closes #30055.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license