avanderm
avanderm

Reputation: 151

CDK Aspects and Tokens which resolve to undefined

I bumped into a problem where we want to make sure some conventions are being followed in the naming of CloudFormation resources. The idea is that we use CDK Aspects to process resources. A simple example:

export class BucketConvention implements cdk.IAspect {
  private readonly ctx: Context;

  constructor(ctx: Context) {
    this.ctx = ctx;
  }

  public visit(node: cdk.IConstruct): void {
    if (cdk.CfnResource.isCfnResource(node) && node.cfnResourceType == 'AWS::S3::Bucket') {
      const resource = node as s3.CfnBucket;
      const resourceId = resource.bucketName ? resource.bucketName : cdk.Stack.of(node).getLogicalId(node);
      resource.addPropertyOverride('BucketName', `${ctx.project}-${ctx.environment}-${resourceId}`);
    }
  }
}

The Context interface simply holds some variables used to create names. The problem with this snippet is that we are trying to interpolate the bucket name if it has been set, if not use the logical ID. Now the method to obtain the logical ID works, however resource.BucketName will return a token of which the resolved value could be undefined (i.e. the user didn't pass a bucket name in constructing the bucket, which happens a lot in high level constructs). So the logical ID will actually never trigger, since a token is always defined. If you would log the interpolation output you could get something like

myproject-myenvironment-${Token[TOKEN.104]}

My question, how can we make this work such that the interpolation happens with the bucket name if it has been supplied and if not use the logical ID? Is there a way to peek whether the token will give an undefined value during synthesis time?

Upvotes: 7

Views: 5782

Answers (1)

avanderm
avanderm

Reputation: 151

And found the answer to my problem... similar to the logical ID you can use

cdk.Stack.of(resource).resolve(resource.bucketName)

Upvotes: 6

Related Questions