From b0f8729002b90c1c90ca46a4db9e297a69fef174 Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Wed, 15 Jul 2020 14:57:10 +0100 Subject: [PATCH] feat(core): cloudformation resource metadata (#9063) Exposes a mechanism to add metadata to CloudFormation resources by key name. This can be used for internal usage like setting the CDK metadata path, or for other metadata like CfnInit use cases. This is a prerequisite of #8788, where it will be used to add CfnInit metadata. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/core/lib/cfn-resource.ts | 20 +++++++++++++--- .../@aws-cdk/core/test/test.cfn-resource.ts | 24 +++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/core/lib/cfn-resource.ts b/packages/@aws-cdk/core/lib/cfn-resource.ts index 68c34c52bce1d..39b60a3d248b7 100644 --- a/packages/@aws-cdk/core/lib/cfn-resource.ts +++ b/packages/@aws-cdk/core/lib/cfn-resource.ts @@ -93,9 +93,7 @@ export class CfnResource extends CfnRefElement { // path in the CloudFormation template, so it will be possible to trace // back to the actual construct path. if (this.node.tryGetContext(cxapi.PATH_METADATA_ENABLE_CONTEXT)) { - this.cfnOptions.metadata = { - [cxapi.PATH_METADATA_KEY]: this.node.path, - }; + this.addMetadata(cxapi.PATH_METADATA_KEY, this.node.path); } } @@ -238,6 +236,22 @@ export class CfnResource extends CfnRefElement { addDependency(this, target, `"${this.node.path}" depends on "${target.node.path}"`); } + /** + * Add a value to the CloudFormation Resource Metadata + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html + * + * Note that this is a different set of metadata from CDK node metadata; this + * metadata ends up in the stack template under the resource, whereas CDK + * node metadata ends up in the Cloud Assembly. + */ + public addMetadata(key: string, value: any) { + if (!this.cfnOptions.metadata) { + this.cfnOptions.metadata = {}; + } + + this.cfnOptions.metadata[key] = value; + } + /** * @returns a string representation of this resource */ diff --git a/packages/@aws-cdk/core/test/test.cfn-resource.ts b/packages/@aws-cdk/core/test/test.cfn-resource.ts index dec09b5c96084..41d360296ec1d 100644 --- a/packages/@aws-cdk/core/test/test.cfn-resource.ts +++ b/packages/@aws-cdk/core/test/test.cfn-resource.ts @@ -73,4 +73,28 @@ export = nodeunit.testCase({ test.done(); }, + + 'can add metadata'(test: nodeunit.Test) { + // GIVEN + const app = new core.App(); + const stack = new core.Stack(app, 'TestStack'); + const resource = new core.CfnResource(stack, 'DefaultResource', { type: 'Test::Resource::Fake' }); + + // WHEN + resource.addMetadata('Beep', 'Boop'); + + // THEN + test.deepEqual(app.synth().getStackByName(stack.stackName).template, { + Resources: { + DefaultResource: { + Type: 'Test::Resource::Fake', + Metadata: { + Beep: 'Boop', + }, + }, + }, + }); + + test.done(); + }, });