Skip to content

Commit

Permalink
chore(core): use key instead of logicalId for key when provided (#28075)
Browse files Browse the repository at this point in the history
In CDK Migrate, when a user has a construct with the same name as their CfnOutput key, it creates a naming collision.

This change enables us to name the construct something else and still use the correct key in creating the output. Note that the logicalId only makes it into the synthesized template as the output key so this change won't impact existing apps using the CfnOutput construct.

Closes #<issue number here>.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
TheRealAmazonKendra authored Nov 20, 2023
1 parent 8eac74d commit be24aa5
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
9 changes: 8 additions & 1 deletion packages/aws-cdk-lib/core/lib/cfn-output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ export interface CfnOutputProps {
*/
readonly description?: string;

/**
* The key of the property returned by aws cloudformation describe-stacks command.
*/
readonly key?: string;

/**
* The value of the property returned by the aws cloudformation describe-stacks command.
* The value of an output can include literals, parameter references, pseudo-parameters,
Expand Down Expand Up @@ -38,6 +43,7 @@ export interface CfnOutputProps {
export class CfnOutput extends CfnElement {
private _description?: string;
private _condition?: CfnCondition;
private _key?: string;
private _value?: any;
private _exportName?: string;

Expand All @@ -58,6 +64,7 @@ export class CfnOutput extends CfnElement {
}

this._description = props.description;
this._key = props.key;
this._value = props.value;
this._condition = props.condition;
this._exportName = props.exportName;
Expand Down Expand Up @@ -160,7 +167,7 @@ export class CfnOutput extends CfnElement {
public _toCloudFormation(): object {
return {
Outputs: {
[this.logicalId]: {
[this._key ?? this.logicalId]: {
Description: this._description,
Value: this._value,
Export: this._exportName != null ? { Name: this._exportName } : undefined,
Expand Down
26 changes: 25 additions & 1 deletion packages/aws-cdk-lib/core/test/output.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ beforeEach(() => {
});

describe('output', () => {
test('outputs can be added to the stack', () => {
test('outputs can be added to the stack with no key provided', () => {
const res = new CfnResource(stack, 'MyResource', { type: 'R' });
const ref = res.ref;

Expand All @@ -32,6 +32,30 @@ describe('output', () => {
});
});

test('outputs can be added to the stack with a key provided', () => {
const res = new CfnResource(stack, 'MyResource', { type: 'R' });
const ref = res.ref;

new CfnOutput(stack, 'MyOutput', {
exportName: 'ExportName',
key: 'MyOutputWithKey',
value: ref,
description: 'CfnOutput properties',
});
expect(toCloudFormation(stack)).toEqual({
Resources: { MyResource: { Type: 'R' } },
Outputs:
{
MyOutputWithKey:
{
Description: 'CfnOutput properties',
Export: { Name: 'ExportName' },
Value: { Ref: 'MyResource' },
},
},
});
});

test('No export is created by default', () => {
// WHEN
new CfnOutput(stack, 'SomeOutput', { value: 'x' });
Expand Down

0 comments on commit be24aa5

Please sign in to comment.