@aws-cdk-testing/cli-integ 3.29.0 → 3.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/npm-shrinkwrap.json +1 -1
- package/package.json +2 -2
- package/resources/cdk-apps/nested-stack-with-fn-join-export/app.js +46 -0
- package/resources/cdk-apps/nested-stack-with-fn-join-export/cdk.json +7 -0
- package/tests/cli-integ-tests/deploy/cdk-deploy-nested-stacks-with-fn-join-export.integtest.d.ts +1 -0
- package/tests/cli-integ-tests/deploy/cdk-deploy-nested-stacks-with-fn-join-export.integtest.js +10 -0
- package/tests/cli-integ-tests/deploy/cdk-deploy-skips-unnecessary-updates-for-nested-stacks.integtest.js +7 -10
package/npm-shrinkwrap.json
CHANGED
package/package.json
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"organization": true
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@aws-cdk/toolkit-lib": "1.21.
|
|
42
|
+
"@aws-cdk/toolkit-lib": "1.21.1",
|
|
43
43
|
"@aws-cdk/yarn-cling": "0.0.0",
|
|
44
44
|
"@cdklabs/eslint-plugin": "^1.5.9",
|
|
45
45
|
"@stylistic/eslint-plugin": "^3",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"publishConfig": {
|
|
116
116
|
"access": "public"
|
|
117
117
|
},
|
|
118
|
-
"version": "3.29.
|
|
118
|
+
"version": "3.29.1",
|
|
119
119
|
"types": "lib/index.d.ts",
|
|
120
120
|
"//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
|
|
121
121
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const cdk = require('aws-cdk-lib');
|
|
2
|
+
const { aws_cloudformation: cfn, aws_sns: sns, aws_ssm: ssm } = cdk;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Reproduces https://t.corp.amazon.com/D423570178
|
|
6
|
+
*
|
|
7
|
+
* When IncludeNestedStacks is true, CloudFormation validates all nested stacks
|
|
8
|
+
* together. Export names using Fn::Join with a runtime reference get collapsed
|
|
9
|
+
* to the placeholder {{IntrinsicFunction://Fn::Join}}, causing a false
|
|
10
|
+
* "duplicate Export names" error when 2+ such exports exist across nested stacks.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
class NestedStackWithFnJoinExports extends cfn.NestedStack {
|
|
14
|
+
constructor(scope, id, props) {
|
|
15
|
+
super(scope, id, props);
|
|
16
|
+
const topic = new sns.Topic(this, 'Topic');
|
|
17
|
+
new cdk.CfnOutput(this, 'ExportArn', {
|
|
18
|
+
value: topic.topicArn,
|
|
19
|
+
exportName: cdk.Fn.join(':', [props.runtimeRef, 'GetAtt', id, 'Arn']),
|
|
20
|
+
});
|
|
21
|
+
new cdk.CfnOutput(this, 'ExportName', {
|
|
22
|
+
value: topic.topicName,
|
|
23
|
+
exportName: cdk.Fn.join(':', [props.runtimeRef, 'GetAtt', id, 'Name']),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
class NestedStacksFnJoinExportStack extends cdk.Stack {
|
|
29
|
+
constructor(scope, id, props) {
|
|
30
|
+
super(scope, id, props);
|
|
31
|
+
// SSM parameter name is a runtime reference (not known at validation time)
|
|
32
|
+
const param = new ssm.StringParameter(this, 'Param', { stringValue: 'value' });
|
|
33
|
+
new NestedStackWithFnJoinExports(this, 'Nested1', { runtimeRef: param.parameterName });
|
|
34
|
+
new NestedStackWithFnJoinExports(this, 'Nested2', { runtimeRef: param.parameterName });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const app = new cdk.App();
|
|
39
|
+
|
|
40
|
+
const stackPrefix = process.env.STACK_NAME_PREFIX;
|
|
41
|
+
if (!stackPrefix) {
|
|
42
|
+
throw new Error('the STACK_NAME_PREFIX environment variable is required');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
new NestedStacksFnJoinExportStack(app, `${stackPrefix}-nested-stacks-fn-join-export`);
|
|
46
|
+
app.synth();
|
package/tests/cli-integ-tests/deploy/cdk-deploy-nested-stacks-with-fn-join-export.integtest.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/tests/cli-integ-tests/deploy/cdk-deploy-nested-stacks-with-fn-join-export.integtest.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const lib_1 = require("../../../lib");
|
|
4
|
+
(0, lib_1.integTest)('deploy nested stacks with Fn::Join export names', (0, lib_1.withSpecificFixture)('nested-stack-with-fn-join-export', async (fixture) => {
|
|
5
|
+
// This should succeed. With IncludeNestedStacks:true, CloudFormation
|
|
6
|
+
// incorrectly reports duplicate export names when multiple nested stacks
|
|
7
|
+
// use Fn::Join with the same runtime reference to build export names.
|
|
8
|
+
await fixture.cdkDeploy('nested-stacks-fn-join-export', { captureStderr: false });
|
|
9
|
+
}));
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrLWRlcGxveS1uZXN0ZWQtc3RhY2tzLXdpdGgtZm4tam9pbi1leHBvcnQuaW50ZWd0ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY2RrLWRlcGxveS1uZXN0ZWQtc3RhY2tzLXdpdGgtZm4tam9pbi1leHBvcnQuaW50ZWd0ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsc0NBQThEO0FBRTlELElBQUEsZUFBUyxFQUNQLGlEQUFpRCxFQUNqRCxJQUFBLHlCQUFtQixFQUFDLGtDQUFrQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUN4RSxxRUFBcUU7SUFDckUseUVBQXlFO0lBQ3pFLHNFQUFzRTtJQUN0RSxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsOEJBQThCLEVBQUUsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztBQUNwRixDQUFDLENBQUMsQ0FDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW50ZWdUZXN0LCB3aXRoU3BlY2lmaWNGaXh0dXJlIH0gZnJvbSAnLi4vLi4vLi4vbGliJztcblxuaW50ZWdUZXN0KFxuICAnZGVwbG95IG5lc3RlZCBzdGFja3Mgd2l0aCBGbjo6Sm9pbiBleHBvcnQgbmFtZXMnLFxuICB3aXRoU3BlY2lmaWNGaXh0dXJlKCduZXN0ZWQtc3RhY2std2l0aC1mbi1qb2luLWV4cG9ydCcsIGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gICAgLy8gVGhpcyBzaG91bGQgc3VjY2VlZC4gV2l0aCBJbmNsdWRlTmVzdGVkU3RhY2tzOnRydWUsIENsb3VkRm9ybWF0aW9uXG4gICAgLy8gaW5jb3JyZWN0bHkgcmVwb3J0cyBkdXBsaWNhdGUgZXhwb3J0IG5hbWVzIHdoZW4gbXVsdGlwbGUgbmVzdGVkIHN0YWNrc1xuICAgIC8vIHVzZSBGbjo6Sm9pbiB3aXRoIHRoZSBzYW1lIHJ1bnRpbWUgcmVmZXJlbmNlIHRvIGJ1aWxkIGV4cG9ydCBuYW1lcy5cbiAgICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnbmVzdGVkLXN0YWNrcy1mbi1qb2luLWV4cG9ydCcsIHsgY2FwdHVyZVN0ZGVycjogZmFsc2UgfSk7XG4gIH0pLFxuKTtcbiJdfQ==
|
|
@@ -3,22 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
|
|
4
4
|
const lib_1 = require("../../../lib");
|
|
5
5
|
(0, lib_1.integTest)('deploy skips unnecessary updates for nested stacks', (0, lib_1.withDefaultFixture)(async (fixture) => {
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
6
|
+
// we are using a stack with a nested stack because CFN will always attempt to
|
|
7
|
+
// update a nested stack, which will allow us to verify that updates are actually
|
|
8
|
+
// skipped unless --force is specified.
|
|
9
9
|
const stackArn = await fixture.cdkDeploy('with-nested-stack', { captureStderr: false });
|
|
10
10
|
const changeSet1 = await getLatestChangeSet();
|
|
11
11
|
// Deploy the same stack again, there should be no new change set created
|
|
12
12
|
await fixture.cdkDeploy('with-nested-stack');
|
|
13
13
|
const changeSet2 = await getLatestChangeSet();
|
|
14
14
|
expect(changeSet2.ChangeSetId).toEqual(changeSet1.ChangeSetId);
|
|
15
|
-
// Deploy the stack again with --force
|
|
16
|
-
|
|
17
|
-
// is not executed and the stack's ChangeSetId remains the same.
|
|
18
|
-
const forceOutput = await fixture.cdk(fixture.cdkDeployCommandLine('with-nested-stack', { options: ['--force'] }));
|
|
19
|
-
expect(forceOutput).toContain('CloudFormation reported that the deployment would not make any changes');
|
|
15
|
+
// Deploy the stack again with --force, now we should create a changeset
|
|
16
|
+
await fixture.cdkDeploy('with-nested-stack', { options: ['--force'] });
|
|
20
17
|
const changeSet3 = await getLatestChangeSet();
|
|
21
|
-
expect(changeSet3.ChangeSetId).toEqual(changeSet2.ChangeSetId);
|
|
18
|
+
expect(changeSet3.ChangeSetId).not.toEqual(changeSet2.ChangeSetId);
|
|
22
19
|
// Deploy the stack again with tags, expected to create a new changeset
|
|
23
20
|
// even though the resources didn't change.
|
|
24
21
|
await fixture.cdkDeploy('with-nested-stack', { options: ['--tags', 'key=value'] });
|
|
@@ -33,4 +30,4 @@ const lib_1 = require("../../../lib");
|
|
|
33
30
|
return response.Stacks?.[0];
|
|
34
31
|
}
|
|
35
32
|
}));
|
|
36
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrLWRlcGxveS1za2lwcy11bm5lY2Vzc2FyeS11cGRhdGVzLWZvci1uZXN0ZWQtc3RhY2tzLmludGVndGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNkay1kZXBsb3ktc2tpcHMtdW5uZWNlc3NhcnktdXBkYXRlcy1mb3ItbmVzdGVkLXN0YWNrcy5pbnRlZ3Rlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwwRUFBdUU7QUFDdkUsc0NBQTZEO0FBRTdELElBQUEsZUFBUyxFQUNQLG9EQUFvRCxFQUNwRCxJQUFBLHdCQUFrQixFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUNuQyw4RUFBOEU7SUFDOUUsaUZBQWlGO0lBQ2pGLHVDQUF1QztJQUN2QyxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN4RixNQUFNLFVBQVUsR0FBRyxNQUFNLGtCQUFrQixFQUFFLENBQUM7SUFFOUMseUVBQXlFO0lBQ3pFLE1BQU0sT0FBTyxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sVUFBVSxHQUFHLE1BQU0sa0JBQWtCLEVBQUUsQ0FBQztJQUM5QyxNQUFNLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUM7SUFFL0Qsd0VBQXdFO0lBQ3hFLE1BQU0sT0FBTyxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLE9BQU8sRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN2RSxNQUFNLFVBQVUsR0FBRyxNQUFNLGtCQUFrQixFQUFFLENBQUM7SUFDOUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUVuRSx1RUFBdUU7SUFDdkUsMkNBQTJDO0lBQzNDLE1BQU0sT0FBTyxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRSxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDbkYsTUFBTSxVQUFVLEdBQUcsTUFBTSxrQkFBa0IsRUFBRSxDQUFDO0lBQzlDLE1BQU0sQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUM7SUFFbkUsS0FBSyxVQUFVLGtCQUFrQjtRQUMvQixNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLDZDQUFxQixDQUFDLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNwRSxPQUFPLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5QixDQUFDO0FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERlc2NyaWJlU3RhY2tzQ29tbWFuZCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jbG91ZGZvcm1hdGlvbic7XG5pbXBvcnQgeyBpbnRlZ1Rlc3QsIHdpdGhEZWZhdWx0Rml4dHVyZSB9IGZyb20gJy4uLy4uLy4uL2xpYic7XG5cbmludGVnVGVzdChcbiAgJ2RlcGxveSBza2lwcyB1bm5lY2Vzc2FyeSB1cGRhdGVzIGZvciBuZXN0ZWQgc3RhY2tzJyxcbiAgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gICAgLy8gd2UgYXJlIHVzaW5nIGEgc3RhY2sgd2l0aCBhIG5lc3RlZCBzdGFjayBiZWNhdXNlIENGTiB3aWxsIGFsd2F5cyBhdHRlbXB0IHRvXG4gICAgLy8gdXBkYXRlIGEgbmVzdGVkIHN0YWNrLCB3aGljaCB3aWxsIGFsbG93IHVzIHRvIHZlcmlmeSB0aGF0IHVwZGF0ZXMgYXJlIGFjdHVhbGx5XG4gICAgLy8gc2tpcHBlZCB1bmxlc3MgLS1mb3JjZSBpcyBzcGVjaWZpZWQuXG4gICAgY29uc3Qgc3RhY2tBcm4gPSBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnd2l0aC1uZXN0ZWQtc3RhY2snLCB7IGNhcHR1cmVTdGRlcnI6IGZhbHNlIH0pO1xuICAgIGNvbnN0IGNoYW5nZVNldDEgPSBhd2FpdCBnZXRMYXRlc3RDaGFuZ2VTZXQoKTtcblxuICAgIC8vIERlcGxveSB0aGUgc2FtZSBzdGFjayBhZ2FpbiwgdGhlcmUgc2hvdWxkIGJlIG5vIG5ldyBjaGFuZ2Ugc2V0IGNyZWF0ZWRcbiAgICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnd2l0aC1uZXN0ZWQtc3RhY2snKTtcbiAgICBjb25zdCBjaGFuZ2VTZXQyID0gYXdhaXQgZ2V0TGF0ZXN0Q2hhbmdlU2V0KCk7XG4gICAgZXhwZWN0KGNoYW5nZVNldDIuQ2hhbmdlU2V0SWQpLnRvRXF1YWwoY2hhbmdlU2V0MS5DaGFuZ2VTZXRJZCk7XG5cbiAgICAvLyBEZXBsb3kgdGhlIHN0YWNrIGFnYWluIHdpdGggLS1mb3JjZSwgbm93IHdlIHNob3VsZCBjcmVhdGUgYSBjaGFuZ2VzZXRcbiAgICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnd2l0aC1uZXN0ZWQtc3RhY2snLCB7IG9wdGlvbnM6IFsnLS1mb3JjZSddIH0pO1xuICAgIGNvbnN0IGNoYW5nZVNldDMgPSBhd2FpdCBnZXRMYXRlc3RDaGFuZ2VTZXQoKTtcbiAgICBleHBlY3QoY2hhbmdlU2V0My5DaGFuZ2VTZXRJZCkubm90LnRvRXF1YWwoY2hhbmdlU2V0Mi5DaGFuZ2VTZXRJZCk7XG5cbiAgICAvLyBEZXBsb3kgdGhlIHN0YWNrIGFnYWluIHdpdGggdGFncywgZXhwZWN0ZWQgdG8gY3JlYXRlIGEgbmV3IGNoYW5nZXNldFxuICAgIC8vIGV2ZW4gdGhvdWdoIHRoZSByZXNvdXJjZXMgZGlkbid0IGNoYW5nZS5cbiAgICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnd2l0aC1uZXN0ZWQtc3RhY2snLCB7IG9wdGlvbnM6IFsnLS10YWdzJywgJ2tleT12YWx1ZSddIH0pO1xuICAgIGNvbnN0IGNoYW5nZVNldDQgPSBhd2FpdCBnZXRMYXRlc3RDaGFuZ2VTZXQoKTtcbiAgICBleHBlY3QoY2hhbmdlU2V0NC5DaGFuZ2VTZXRJZCkubm90LnRvRXF1YWwoY2hhbmdlU2V0My5DaGFuZ2VTZXRJZCk7XG5cbiAgICBhc3luYyBmdW5jdGlvbiBnZXRMYXRlc3RDaGFuZ2VTZXQoKSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uLnNlbmQobmV3IERlc2NyaWJlU3RhY2tzQ29tbWFuZCh7IFN0YWNrTmFtZTogc3RhY2tBcm4gfSkpO1xuICAgICAgaWYgKCFyZXNwb25zZS5TdGFja3M/LlswXSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpZCBub3QgZ2V0IGEgQ2hhbmdlU2V0IGF0IGFsbCcpO1xuICAgICAgfVxuICAgICAgZml4dHVyZS5sb2coYEZvdW5kIENoYW5nZSBTZXQgJHtyZXNwb25zZS5TdGFja3M/LlswXS5DaGFuZ2VTZXRJZH1gKTtcbiAgICAgIHJldHVybiByZXNwb25zZS5TdGFja3M/LlswXTtcbiAgICB9XG4gIH0pLFxuKTtcbiJdfQ==
|