Skip to content

Commit 2e080fe

Browse files
authored
feat(core): add description to exportValue and exportStringListValue methods (#29150)
### Issue # (if applicable) Closes #29092. ### Reason for this change To be able to set the description of the `CfnOutput` created when using `exportValue` and `exportStringListValue`. ### Description of changes Add property `description` to `ExportValueOptions` interface. ### Description of how you validated changes Both unit and integ tests ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent ea201d0 commit 2e080fe

File tree

11 files changed

+176
-24
lines changed

11 files changed

+176
-24
lines changed

packages/@aws-cdk-testing/framework-integ/test/core/test/integ.stack.js.snapshot/Stack.assets.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/core/test/integ.stack.js.snapshot/Stack.template.json

+16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
11
{
2+
"Outputs": {
3+
"ExportMyExportValue": {
4+
"Description": "This is a description for MyExportValue",
5+
"Value": "someValue",
6+
"Export": {
7+
"Name": "MyExportValue"
8+
}
9+
},
10+
"ExportMyExportStringListValue": {
11+
"Description": "This is a description for MyExportStringListValue",
12+
"Value": "someValue||anotherValue",
13+
"Export": {
14+
"Name": "MyExportStringListValue"
15+
}
16+
}
17+
},
218
"Parameters": {
319
"BootstrapVersion": {
420
"Type": "AWS::SSM::Parameter::Value<String>",

packages/@aws-cdk-testing/framework-integ/test/core/test/integ.stack.js.snapshot/cdk.out

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/core/test/integ.stack.js.snapshot/integ.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/core/test/integ.stack.js.snapshot/manifest.json

+14-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/core/test/integ.stack.js.snapshot/stackDefaultTestDeployAssert0386B0AD.assets.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/core/test/integ.stack.js.snapshot/tree.json

+32-16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/core/test/integ.stack.ts

+9
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,13 @@ const app = new cdk.App();
99
const stack = new cdk.Stack(app, 'Stack', { terminationProtection: false });
1010
stack.terminationProtection = true;
1111

12+
stack.exportValue('someValue', {
13+
name: 'MyExportValue',
14+
description: 'This is a description for MyExportValue',
15+
});
16+
stack.exportStringListValue(['someValue', 'anotherValue'], {
17+
name: 'MyExportStringListValue',
18+
description: 'This is a description for MyExportStringListValue',
19+
});
20+
1221
new IntegTest(app, 'stack', { testCases: [stack] });

packages/aws-cdk-lib/core/README.md

+11
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,17 @@ new CfnOutput(this, 'OutputName', {
836836
});
837837
```
838838

839+
You can also use the `exportValue` method to export values as stack outputs:
840+
841+
```ts
842+
declare const stack: Stack;
843+
844+
stack.exportValue(myBucket.bucketName, {
845+
name: 'TheAwesomeBucket',
846+
description: 'The name of an S3 bucket',
847+
});
848+
```
849+
839850
[cfn-stack-output]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html
840851

841852
### Parameters

packages/aws-cdk-lib/core/lib/stack.ts

+11
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,7 @@ export class Stack extends Construct implements ITaggable {
12041204
new CfnOutput(this, `Export${options.name}`, {
12051205
value: exportedValue,
12061206
exportName: options.name,
1207+
description: options.description,
12071208
});
12081209
return Fn.importValue(options.name);
12091210
}
@@ -1215,6 +1216,7 @@ export class Stack extends Construct implements ITaggable {
12151216
new CfnOutput(exportsScope, id, {
12161217
value: Token.asString(exportable),
12171218
exportName,
1219+
description: options.description,
12181220
});
12191221
}
12201222

@@ -1253,6 +1255,7 @@ export class Stack extends Construct implements ITaggable {
12531255
new CfnOutput(this, `Export${options.name}`, {
12541256
value: Fn.join(STRING_LIST_REFERENCE_DELIMITER, exportedValue),
12551257
exportName: options.name,
1258+
description: options.description,
12561259
});
12571260
return Fn.split(STRING_LIST_REFERENCE_DELIMITER, Fn.importValue(options.name));
12581261
}
@@ -1268,6 +1271,7 @@ export class Stack extends Construct implements ITaggable {
12681271
// (string lists are invalid)
12691272
value: Fn.join(STRING_LIST_REFERENCE_DELIMITER, Token.asList(exportable)),
12701273
exportName,
1274+
description: options.description,
12711275
});
12721276
}
12731277

@@ -1766,6 +1770,13 @@ export interface ExportValueOptions {
17661770
* @default - A name is automatically chosen
17671771
*/
17681772
readonly name?: string;
1773+
1774+
/**
1775+
* The description of the outputs
1776+
*
1777+
* @default - No description
1778+
*/
1779+
readonly description?: string;
17691780
}
17701781

17711782
function count(xs: string[]): Record<string, number> {

packages/aws-cdk-lib/core/test/stack.test.ts

+77
Original file line numberDiff line numberDiff line change
@@ -1489,6 +1489,83 @@ describe('stack', () => {
14891489
});
14901490
});
14911491

1492+
test('exports with name can include description', () => {
1493+
const app = new App();
1494+
const stack = new Stack(app, 'Stack');
1495+
1496+
stack.exportValue('someValue', {
1497+
name: 'MyExport',
1498+
description: 'This is a description',
1499+
});
1500+
1501+
const template = app.synth().getStackByName(stack.stackName).template;
1502+
expect(template).toMatchObject({
1503+
Outputs: {
1504+
ExportMyExport: {
1505+
Description: 'This is a description',
1506+
},
1507+
},
1508+
});
1509+
});
1510+
1511+
test('list exports with name can include description', () => {
1512+
const app = new App();
1513+
const stack = new Stack(app, 'Stack');
1514+
1515+
stack.exportStringListValue(['someValue', 'anotherValue'], {
1516+
name: 'MyExport',
1517+
description: 'This is a description',
1518+
});
1519+
1520+
const template = app.synth().getStackByName(stack.stackName).template;
1521+
expect(template).toMatchObject({
1522+
Outputs: {
1523+
ExportMyExport: {
1524+
Description: 'This is a description',
1525+
},
1526+
},
1527+
});
1528+
});
1529+
1530+
test('exports without name can include description', () => {
1531+
const app = new App();
1532+
const stack = new Stack(app, 'Stack');
1533+
1534+
const resource = new CfnResource(stack, 'Resource', { type: 'AWS::Resource' });
1535+
stack.exportValue(resource.getAtt('Att'), {
1536+
description: 'This is a description',
1537+
});
1538+
1539+
const template = app.synth().getStackByName(stack.stackName).template;
1540+
expect(template).toMatchObject({
1541+
Outputs: {
1542+
ExportsOutputFnGetAttResourceAttB5968E71: {
1543+
Description: 'This is a description',
1544+
},
1545+
},
1546+
});
1547+
});
1548+
1549+
test('list exports without name can include description', () => {
1550+
const app = new App();
1551+
const stack = new Stack(app, 'Stack');
1552+
1553+
const resource = new CfnResource(stack, 'Resource', { type: 'AWS::Resource' });
1554+
(resource as any).attrAtt = ['Foo', 'Bar'];
1555+
stack.exportStringListValue(resource.getAtt('Att', ResolutionTypeHint.STRING_LIST), {
1556+
description: 'This is a description',
1557+
});
1558+
1559+
const template = app.synth().getStackByName(stack.stackName).template;
1560+
expect(template).toMatchObject({
1561+
Outputs: {
1562+
ExportsOutputFnGetAttResourceAttB5968E71: {
1563+
Description: 'This is a description',
1564+
},
1565+
},
1566+
});
1567+
});
1568+
14921569
test('CfnSynthesisError is ignored when preparing cross references', () => {
14931570
// GIVEN
14941571
const app = new App();

0 commit comments

Comments
 (0)