From 2321eced6cc16925c6d50e35b140f9ad4008d758 Mon Sep 17 00:00:00 2001 From: Adam Ruka Date: Fri, 1 Apr 2022 04:20:43 -0700 Subject: [PATCH] fix(cli): support attributes of DynamoDB Tables for hotswapping (#19620) When using Nested Stacks, Parameters are used to pass values between the parent and child Stacks. A customer had a setup where a DynamoDB Table was in the parent Stack, and a Lambda using that Table (through environment variables) was in the child Stack. In order to be able to hotswap the Lambda in the child Stack, we have to correctly resolve attributes of the `AWS::DynamoDB::Table` resource, like `Ref` and `Arn`, to resolve the values of the Parameters passed to the child Stack. Fixes #19421 ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/master/INTEGRATION_TESTS.md)? * [ ] Did you use `cdk-integ` to deploy the infrastructure and generate the snapshot (i.e. `cdk-integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../api/evaluate-cloudformation-template.ts | 1 + .../state-machine-hotswap-deployments.test.ts | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/packages/aws-cdk/lib/api/evaluate-cloudformation-template.ts b/packages/aws-cdk/lib/api/evaluate-cloudformation-template.ts index 56cdb394fee31..534066445cc0b 100644 --- a/packages/aws-cdk/lib/api/evaluate-cloudformation-template.ts +++ b/packages/aws-cdk/lib/api/evaluate-cloudformation-template.ts @@ -360,6 +360,7 @@ const RESOURCE_TYPE_ATTRIBUTES_FORMATS: { [type: string]: { [attribute: string]: // the name attribute of the EventBus is the same as the Ref Name: parts => parts.resourceName, }, + 'AWS::DynamoDB::Table': { Arn: stdSlashResourceArnFmt }, 'AWS::AppSync::GraphQLApi': { ApiId: appsyncGraphQlApiApiIdFmt }, }; diff --git a/packages/aws-cdk/test/api/hotswap/state-machine-hotswap-deployments.test.ts b/packages/aws-cdk/test/api/hotswap/state-machine-hotswap-deployments.test.ts index e5b84a1c7095c..54580f2927fc8 100644 --- a/packages/aws-cdk/test/api/hotswap/state-machine-hotswap-deployments.test.ts +++ b/packages/aws-cdk/test/api/hotswap/state-machine-hotswap-deployments.test.ts @@ -558,3 +558,82 @@ test('knows how to handle attributes of the AWS::Events::EventBus resource', asy }), }); }); + +test('knows how to handle attributes of the AWS::DynamoDB::Table resource', async () => { + // GIVEN + setup.setCurrentCfnStackTemplate({ + Resources: { + Table: { + Type: 'AWS::DynamoDB::Table', + Properties: { + KeySchema: [{ + AttributeName: 'name', + KeyType: 'HASH', + }], + AttributeDefinitions: [{ + AttributeName: 'name', + AttributeType: 'S', + }], + BillingMode: 'PAY_PER_REQUEST', + }, + }, + Machine: { + Type: 'AWS::StepFunctions::StateMachine', + Properties: { + DefinitionString: '{}', + StateMachineName: 'my-machine', + }, + }, + }, + }); + setup.pushStackResourceSummaries( + setup.stackSummaryOf('Table', 'AWS::DynamoDB::Table', 'my-dynamodb-table'), + ); + const cdkStackArtifact = setup.cdkStackArtifactOf({ + template: { + Resources: { + Table: { + Type: 'AWS::DynamoDB::Table', + Properties: { + KeySchema: [{ + AttributeName: 'name', + KeyType: 'HASH', + }], + AttributeDefinitions: [{ + AttributeName: 'name', + AttributeType: 'S', + }], + BillingMode: 'PAY_PER_REQUEST', + }, + }, + Machine: { + Type: 'AWS::StepFunctions::StateMachine', + Properties: { + DefinitionString: { + 'Fn::Join': ['', [ + '{"TableName":"', + { Ref: 'Table' }, + '","TableArn":"', + { 'Fn::GetAtt': ['Table', 'Arn'] }, + '"}', + ]], + }, + StateMachineName: 'my-machine', + }, + }, + }, + }, + }); + + // THEN + const result = await hotswapMockSdkProvider.tryHotswapDeployment(cdkStackArtifact); + + expect(result).not.toBeUndefined(); + expect(mockUpdateMachineDefinition).toHaveBeenCalledWith({ + stateMachineArn: 'arn:aws:states:here:123456789012:stateMachine:my-machine', + definition: JSON.stringify({ + TableName: 'my-dynamodb-table', + TableArn: 'arn:aws:dynamodb:here:123456789012:table/my-dynamodb-table', + }), + }); +});