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

Cannot use tokens when tagging stacks #4106

Closed
caphrim007 opened this issue Sep 16, 2019 · 4 comments
Closed

Cannot use tokens when tagging stacks #4106

caphrim007 opened this issue Sep 16, 2019 · 4 comments
Assignees
Labels
@aws-cdk/core Related to core CDK functionality bug This issue is a bug.

Comments

@caphrim007
Copy link

caphrim007 commented Sep 16, 2019

🐛 Bug Report

What is the problem?

Specifying core.Aws.STACK_NAME as a value to the Stack wide Tags causes cdk deploy to report an error. The same configuration is not reported as erroneous when using cdk synth. Tags are supported on all the resources in use (S3, DynamoDB table, and Kinesis stream).

Reproduction Steps

Using this file

from aws_cdk.core import App, Aws, Stack, Tag
from aws_cdk import aws_s3 as s3

class ServiceStack(Stack):
    def __init__(self, app: App, id: str, **kwargs) -> None:
        super().__init__(app, id, **kwargs)

        # Define S3 service
        r3 = s3.Bucket(self, 'Bucket')

        # Add tags to all resources in the stack
        Tag.add(self, 'Instance', Aws.STACK_NAME)

app = App()
ServiceStack(app, "s1")
app.synth()

And then running this command

cdk deploy

Verbose Log

s1: deploying...
s1: creating CloudFormation changeset...

 ❌  s1 failed: InvalidParameterType: Expected params.Tags[0].Value to be a string
    at ParamValidator.fail (/usr/local/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/param_validator.js:50:37)
    at ParamValidator.validateType (/usr/local/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/param_validator.js:232:10)
    at ParamValidator.validateString (/usr/local/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/param_validator.js:154:32)
    at ParamValidator.validateScalar (/usr/local/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/param_validator.js:130:21)
    at ParamValidator.validateMember (/usr/local/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/param_validator.js:94:21)
    at ParamValidator.validateStructure (/usr/local/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/param_validator.js:75:14)
    at ParamValidator.validateMember (/usr/local/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/param_validator.js:88:21)
    at ParamValidator.validateList (/usr/local/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/param_validator.js:103:14)
    at ParamValidator.validateMember (/usr/local/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/param_validator.js:90:21)
    at ParamValidator.validateStructure (/usr/local/lib/node_modules/aws-cdk/node_modules/aws-sdk/lib/param_validator.js:75:14) {
  message: 'Expected params.Tags[0].Value to be a string',
  code: 'InvalidParameterType',
  time: 2019-09-16T21:40:53.822Z
}
Expected params.Tags[0].Value to be a string

Environment

  • CDK CLI Version: 1.8.0 (build 5244f97)
  • Module Version:
  • OS: OSX
  • Language: Python

Other information

Generated synth output is

Resources:
  Bucket83908E77:
    Type: AWS::S3::Bucket
    Properties:
      Tags:
        - Key: Instance
          Value:
            Ref: AWS::StackName
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
    Metadata:
      aws:cdk:path: s1/Bucket/Resource

Which boots fine in CloudFormation if you manually upload the template

@caphrim007 caphrim007 added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Sep 16, 2019
@SomayaB SomayaB added the language/python Related to Python bindings label Sep 17, 2019
@SomayaB SomayaB added the @aws-cdk/core Related to core CDK functionality label Sep 17, 2019
@eladb
Copy link
Contributor

eladb commented Sep 18, 2019

The issue is that you applying the tag on the entire stack (self as the first parameter to Tag.add), which means that the CLI attempts to apply these tags to the stack, which can only be done when it deploys through CloudFormation. Since { "Ref": "AWS::StackName" } is only resolved during deployment, the result is this error.

We won't be able to support deploy-time values in stack tags, but we should definitely improve this experience:

  1. We should emit an error if you try to apply a tag that uses tokens to the Stack itself.
  2. We should give you a way to opt-out of stack tags

In the meantime, you can do two things:

  1. Use stack.stackName (which resolves to the concrete stack name) instead of Aws.STACK_NAME.
  2. Apply the tag to a specific resource (i.e. the bucket: Tag.add(r3, 'Instance', ...)
  3. If your goal is to apply the same tag to all resources in your stack, you can wrap them in a construct and apply the tag to the construct:
group = Construct(self, 'Group')

r3 = s3.Bucket(group, 'Bucket')
Tag.add(group, 'Instance', Aws.STACK_NAME)

Let me know if this helps.

@eladb eladb removed language/python Related to Python bindings needs-triage This issue or PR still needs to be triaged. labels Sep 18, 2019
@eladb eladb changed the title Using AWS::StackName as a Ref in Tags reports InvalidParameterType Cannot use tokens when tagging stacks Sep 18, 2019
@caphrim007
Copy link
Author

caphrim007 commented Sep 18, 2019

@eladb can you provide insight into when you say "only resolved during deployment", I was only receiving this error when I was using cdk deploy.

Is that not the "during deployment" you're referring to? ergo, shouldn't it be resolved?

I'm guessing there's a step in cdk's workflow that I'm not understanding.

Your guess that I want to apply tags to all the resources in my stack that support them (without having to repeat myself for each resource) though is correct

@eladb
Copy link
Contributor

eladb commented Sep 18, 2019

When I say "during deployment" I mean "resolved by CloudFormation when the stack is deployed". Stack-level tags are specified when the CLI invokes the CreateChangeSet CloudFormation API to request to begin deployment.

To achieve what you want, use workaround #3 above. You can just add all the resources into a sub-construct in your stack (group in the above example) and then tag this construct instead of the stack.

@caphrim007
Copy link
Author

Thanks @eladb !

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.
Projects
None yet
Development

No branches or pull requests

4 participants