aws-cdk icon indicating copy to clipboard operation
aws-cdk copied to clipboard

(core): validate that tokens cannot be used for stack tags

Open starchx opened this issue 3 years ago • 5 comments

Stack level Tag values are not resolved, when the value of the Tag is from stack parameters. This could be a feature request if not a bug.

Reproduction Steps

  constructor(scope: App, id: string, props: StackProps) {
    super(scope, id, props);

    // add stack parameters, and add them as stack level tags
    const paramNames = ['myParam1', 'myParam2'];
    for (const param of paramNames) {
      const requiredCfnParam = new CfnParameter(this, param, {
        type: 'String',
      });
      Tags.of(this).add(param, requiredCfnParam.valueAsString);
    }
  }

deploy stack with:

cdk deploy --parameters myParam1=myValue1 --parameters myParam2=myValue2

After stack deployed, all the resources in the stack have the correct Tag and values applied, however, the stack itself has the correct Tag key, but not the correct value.

What did you expect to happen?

The stack level tags also have correct values.

myParam1     >> value is >>   myValue1
myParam2     >> value is >>   myValue2

What actually happened?

The stack level tags have unresolved token as tag value:

myParam1     >> value is >>   ${Token[TOKEN.191]}
myParam2     >> value is >>   ${Token[TOKEN.192]}

Environment

  • CDK CLI Version : 1.116
  • Framework Version:
  • Node.js Version: v14.15.4
  • OS : mac
  • Language (Version): TypeScript ~4.1.4

Other

If it is a feature request, is there a quick workaround applicable? Thanks.


This is :bug: Bug Report

starchx avatar Sep 02 '21 10:09 starchx

We have also seen this issue on S3 bucket auto empty custom resource:

image

starchx avatar Sep 03 '21 02:09 starchx

I cannot reproduce this.

When I do:

export class TestTokenTagsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here

    new s3.Bucket(this, 'Bucket');

    // add stack parameters, and add them as stack level tags
    const paramNames = ['myParam1', 'myParam2'];
    for (const param of paramNames) {
      const requiredCfnParam = new cdk.CfnParameter(this, param, {
        type: 'String',
      });
      cdk.Tags.of(this).add(param, requiredCfnParam.valueAsString);
    }
  }
}

And then run cdk synth the template looks like:

Resources:
  Bucket83908E77:
    Type: AWS::S3::Bucket
    Properties:
      Tags:
        - Key: myParam1
          Value:
            Ref: myParam1
        - Key: myParam2
          Value:
            Ref: myParam2

Which is correct.

Can you provide a minimal reproducing example?

rix0rrr avatar Sep 07 '21 09:09 rix0rrr

@rix0rrr Thanks for checking. It is the stack level tags that are not resolving. Can you deploy that stack and check the tags for that stack via CloudFormation console?

The other case it happened was the custom resource, such as S3 bucket auto empty custom resource, also had unresolved tag values.

starchx avatar Sep 07 '21 11:09 starchx

Ohhh! Yes, that actually makes sense. A tag that gets applied to a Stack cannot be a reference to a parameter on that same stack, because they execute in different domains. It needs to be a known value at synthesis time.

We should add validation that tells you this cannot work.

rix0rrr avatar Sep 22 '21 07:09 rix0rrr

This issue has not received any attention in 1 year. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

github-actions[bot] avatar Sep 22 '22 08:09 github-actions[bot]