From 32654f573651dd099e8e1b6823ef1934e03660dd Mon Sep 17 00:00:00 2001 From: Masashi Tomooka Date: Tue, 18 Jul 2023 22:47:39 +0900 Subject: [PATCH] fix(cli): hotswap doesn't update SSM parameter environment variables properly (#26382) Closes #25387 Closes #25483 The actual value for a CfnParameter backed by a SSM parameter is returned via `ResolvedValue` (and only for SSM parameters, [doc](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Parameter.html#API_Parameter_Contents)). We use the field from DescirbeStacks API response to populate `stackParams`, instead of `ParameterValue`, which is just a parameter's name. As far as I checked it is not a breaking change. The `parameter` field is not a public API, and internally the values of SSM parameters are only used for hotswap. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-cdk/lib/api/util/cloudformation.ts | 2 +- .../aws-cdk/test/api/deploy-stack.test.ts | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk/lib/api/util/cloudformation.ts b/packages/aws-cdk/lib/api/util/cloudformation.ts index 601b57c75aee8..6f66e6dc220b4 100644 --- a/packages/aws-cdk/lib/api/util/cloudformation.ts +++ b/packages/aws-cdk/lib/api/util/cloudformation.ts @@ -156,7 +156,7 @@ export class CloudFormationStack { if (!this.exists) { return {}; } const ret: Record = {}; for (const param of this.stack!.Parameters ?? []) { - ret[param.ParameterKey!] = param.ParameterValue!; + ret[param.ParameterKey!] = param.ResolvedValue ?? param.ParameterValue!; } return ret; } diff --git a/packages/aws-cdk/test/api/deploy-stack.test.ts b/packages/aws-cdk/test/api/deploy-stack.test.ts index f4c23b00db1c3..e3bda40dfde2c 100644 --- a/packages/aws-cdk/test/api/deploy-stack.test.ts +++ b/packages/aws-cdk/test/api/deploy-stack.test.ts @@ -149,6 +149,36 @@ test('correctly passes CFN parameters when hotswapping', async () => { expect(tryHotswapDeployment).toHaveBeenCalledWith(expect.anything(), { A: 'A-value', B: 'B=value' }, expect.anything(), expect.anything(), HotswapMode.FALL_BACK); }); +test('correctly passes SSM parameters when hotswapping', async () => { + // GIVEN + givenStackExists({ + Parameters: [ + { ParameterKey: 'SomeParameter', ParameterValue: 'ParameterName', ResolvedValue: 'SomeValue' }, + ], + }); + + // WHEN + await deployStack({ + ...standardDeployStackArguments(), + stack: testStack({ + stackName: 'stack', + template: { + Parameters: { + SomeParameter: { + Type: 'AWS::SSM::Parameter::Value', + Default: 'ParameterName', + }, + }, + }, + }), + hotswap: HotswapMode.FALL_BACK, + usePreviousParameters: true, + }); + + // THEN + expect(tryHotswapDeployment).toHaveBeenCalledWith(expect.anything(), { SomeParameter: 'SomeValue' }, expect.anything(), expect.anything(), HotswapMode.FALL_BACK); +}); + test('call CreateStack when method=direct and the stack doesnt exist yet', async () => { // WHEN await deployStack({