diff --git a/packages/aws-cdk/lib/api/deploy-stack.ts b/packages/aws-cdk/lib/api/deploy-stack.ts index 76b9386cc9550..d8f8a390677bf 100644 --- a/packages/aws-cdk/lib/api/deploy-stack.ts +++ b/packages/aws-cdk/lib/api/deploy-stack.ts @@ -299,6 +299,7 @@ async function prepareAndExecuteChangeSet( StackName: deployName, ChangeSetName: changeSetName, ChangeSetType: update ? 'UPDATE' : 'CREATE', + IncludeNestedStacks: true, Description: `CDK Changeset for execution ${executionId}`, TemplateBody: bodyParameter.TemplateBody, TemplateURL: bodyParameter.TemplateURL, diff --git a/packages/aws-cdk/test/api/deploy-stack.test.ts b/packages/aws-cdk/test/api/deploy-stack.test.ts index 2b199ea225b87..d8eb55bf77eaa 100644 --- a/packages/aws-cdk/test/api/deploy-stack.test.ts +++ b/packages/aws-cdk/test/api/deploy-stack.test.ts @@ -164,6 +164,18 @@ test('correctly passes CFN parameters, ignoring ones with empty values', async ( })); }); +test('correctly passes IncludeNestedStacks', async () => { + // WHEN + await deployStack({ + ...standardDeployStackArguments(), + }); + + // THEN + expect(cfnMocks.createChangeSet).toHaveBeenCalledWith(expect.objectContaining({ + IncludeNestedStacks: true, + })); +}); + test('reuse previous parameters if requested', async () => { // GIVEN givenStackExists({ diff --git a/packages/aws-cdk/test/integ/cli/cli.integtest.ts b/packages/aws-cdk/test/integ/cli/cli.integtest.ts index 7f65950550cb4..627dc150c36bf 100644 --- a/packages/aws-cdk/test/integ/cli/cli.integtest.ts +++ b/packages/aws-cdk/test/integ/cli/cli.integtest.ts @@ -638,10 +638,13 @@ integTest('fast deploy', withDefaultFixture(async (fixture) => { const changeSet2 = await getLatestChangeSet(); expect(changeSet2.ChangeSetId).toEqual(changeSet1.ChangeSetId); - // Deploy the stack again with --force, now we should create a changeset - await fixture.cdkDeploy('with-nested-stack', { options: ['--force'] }); + // Deploy the stack again with --force. This creates a changeset which will be + // empty (since CFN now tracks changes into nested stacks as well), so we delete + // it again because it couldn't be executed anyway. + const output = await fixture.cdkDeploy('with-nested-stack', { options: ['--force'] }); const changeSet3 = await getLatestChangeSet(); - expect(changeSet3.ChangeSetId).not.toEqual(changeSet2.ChangeSetId); + expect(output).toContain('No changes are to be performed on'); + expect(changeSet3.ChangeSetId).toEqual(changeSet2.ChangeSetId); // Deploy the stack again with tags, expected to create a new changeset // even though the resources didn't change. diff --git a/packages/aws-cdk/test/integ/helpers/cdk.ts b/packages/aws-cdk/test/integ/helpers/cdk.ts index 75787ab7b747c..62a6abd08afce 100644 --- a/packages/aws-cdk/test/integ/helpers/cdk.ts +++ b/packages/aws-cdk/test/integ/helpers/cdk.ts @@ -720,11 +720,9 @@ export async function installNpmPackages(fixture: TestFixture, packages: Record< const installNpm7 = memoize0(async (): Promise => { const installDir = path.join(os.tmpdir(), 'cdk-integ-npm7'); await shell(['rm', '-rf', installDir]); - await shell(['mkdir', '-p', installDir]); + await shell(['mkdir', '-p', `${installDir}/node_modules`]); - await shell(['npm', 'install', - '--prefix', installDir, - 'npm@7']); + await shell(['npm', 'install', 'npm@7'], { cwd: installDir }); return path.join(installDir, 'node_modules', '.bin', 'npm'); });