Skip to content

Commit bdaa087

Browse files
feat(toolkit-lib): add support for AWS::DynamoDB::GlobalTable and AWS::Lambda::Url Arn attributes
- Add AWS::DynamoDB::GlobalTable to RESOURCE_TYPE_ATTRIBUTES_FORMATS - Add AWS::Lambda::Url to RESOURCE_TYPE_ATTRIBUTES_FORMATS - Add comprehensive test cases for both GlobalTable and Lambda URL Arn attributes in hotswap - Fixes issue where cdk watch would fail with unsupported resource attributes Fixes #35688
1 parent e46adaf commit bdaa087

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

packages/@aws-cdk/toolkit-lib/lib/api/cloudformation/evaluate-cloudformation-template.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,12 +515,14 @@ const RESOURCE_TYPE_ATTRIBUTES_FORMATS: {
515515
'AWS::IAM::Group': { Arn: iamArnFmt },
516516
'AWS::S3::Bucket': { Arn: s3ArnFmt },
517517
'AWS::Lambda::Function': { Arn: stdColonResourceArnFmt },
518+
"AWS::Lambda::Url": { Arn: stdSlashResourceArnFmt },
518519
'AWS::Events::EventBus': {
519520
Arn: stdSlashResourceArnFmt,
520521
// the name attribute of the EventBus is the same as the Ref
521522
Name: (parts) => parts.resourceName,
522523
},
523524
'AWS::DynamoDB::Table': { Arn: stdSlashResourceArnFmt },
525+
"AWS::DynamoDB::GlobalTable": { Arn: stdSlashResourceArnFmt },
524526
'AWS::AppSync::GraphQLApi': { ApiId: appsyncGraphQlApiApiIdFmt },
525527
'AWS::AppSync::FunctionConfiguration': {
526528
FunctionId: appsyncGraphQlFunctionIDFmt,

packages/@aws-cdk/toolkit-lib/test/api/hotswap/state-machine-hotswap-deployments.test.ts

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,157 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
717717
});
718718
});
719719

720+
test('knows how to handle attributes of the AWS::DynamoDB::GlobalTable resource', async () => {
721+
// GIVEN
722+
setup.setCurrentCfnStackTemplate({
723+
Resources: {
724+
GlobalTable: {
725+
Type: 'AWS::DynamoDB::GlobalTable',
726+
Properties: {
727+
KeySchema: [
728+
{
729+
AttributeName: 'name',
730+
KeyType: 'HASH',
731+
},
732+
],
733+
AttributeDefinitions: [
734+
{
735+
AttributeName: 'name',
736+
AttributeType: 'S',
737+
},
738+
],
739+
BillingMode: 'PAY_PER_REQUEST',
740+
Replicas: [
741+
{
742+
Region: 'us-east-1',
743+
},
744+
],
745+
},
746+
},
747+
Machine: {
748+
Type: 'AWS::StepFunctions::StateMachine',
749+
Properties: {
750+
DefinitionString: '{}',
751+
StateMachineName: 'my-machine',
752+
},
753+
},
754+
},
755+
});
756+
setup.pushStackResourceSummaries(setup.stackSummaryOf('GlobalTable', 'AWS::DynamoDB::GlobalTable', 'my-global-table'));
757+
const cdkStackArtifact = setup.cdkStackArtifactOf({
758+
template: {
759+
Resources: {
760+
GlobalTable: {
761+
Type: 'AWS::DynamoDB::GlobalTable',
762+
Properties: {
763+
KeySchema: [
764+
{
765+
AttributeName: 'name',
766+
KeyType: 'HASH',
767+
},
768+
],
769+
AttributeDefinitions: [
770+
{
771+
AttributeName: 'name',
772+
AttributeType: 'S',
773+
},
774+
],
775+
BillingMode: 'PAY_PER_REQUEST',
776+
Replicas: [
777+
{
778+
Region: 'us-east-1',
779+
},
780+
],
781+
},
782+
},
783+
Machine: {
784+
Type: 'AWS::StepFunctions::StateMachine',
785+
Properties: {
786+
DefinitionString: {
787+
'Fn::Join': [
788+
'',
789+
['{"TableName":"', { Ref: 'GlobalTable' }, '","TableArn":"', { 'Fn::GetAtt': ['GlobalTable', 'Arn'] }, '"}'],
790+
],
791+
},
792+
StateMachineName: 'my-machine',
793+
},
794+
},
795+
},
796+
},
797+
});
798+
799+
// THEN
800+
const result = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
801+
802+
expect(result).not.toBeUndefined();
803+
expect(mockStepFunctionsClient).toHaveReceivedCommandWith(UpdateStateMachineCommand, {
804+
stateMachineArn: 'arn:swa:states:here:123456789012:stateMachine:my-machine',
805+
definition: JSON.stringify({
806+
TableName: 'my-global-table',
807+
TableArn: 'arn:swa:dynamodb:here:123456789012:globaltable/my-global-table',
808+
}),
809+
});
810+
});
811+
812+
test('knows how to handle attributes of the AWS::Lambda::Url resource', async () => {
813+
// GIVEN
814+
setup.setCurrentCfnStackTemplate({
815+
Resources: {
816+
LambdaUrl: {
817+
Type: 'AWS::Lambda::Url',
818+
Properties: {
819+
TargetFunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:my-function',
820+
AuthType: 'NONE',
821+
},
822+
},
823+
Machine: {
824+
Type: 'AWS::StepFunctions::StateMachine',
825+
Properties: {
826+
DefinitionString: '{}',
827+
StateMachineName: 'my-machine',
828+
},
829+
},
830+
},
831+
});
832+
setup.pushStackResourceSummaries(setup.stackSummaryOf('LambdaUrl', 'AWS::Lambda::Url', 'my-lambda-url'));
833+
const cdkStackArtifact = setup.cdkStackArtifactOf({
834+
template: {
835+
Resources: {
836+
LambdaUrl: {
837+
Type: 'AWS::Lambda::Url',
838+
Properties: {
839+
TargetFunctionArn: 'arn:aws:lambda:us-east-1:123456789012:function:my-function',
840+
AuthType: 'NONE',
841+
},
842+
},
843+
Machine: {
844+
Type: 'AWS::StepFunctions::StateMachine',
845+
Properties: {
846+
DefinitionString: {
847+
'Fn::Join': [
848+
'',
849+
['{"UrlArn":"', { 'Fn::GetAtt': ['LambdaUrl', 'Arn'] }, '"}'],
850+
],
851+
},
852+
StateMachineName: 'my-machine',
853+
},
854+
},
855+
},
856+
},
857+
});
858+
859+
// THEN
860+
const result = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
861+
862+
expect(result).not.toBeUndefined();
863+
expect(mockStepFunctionsClient).toHaveReceivedCommandWith(UpdateStateMachineCommand, {
864+
stateMachineArn: 'arn:swa:states:here:123456789012:stateMachine:my-machine',
865+
definition: JSON.stringify({
866+
UrlArn: 'arn:swa:lambda:here:123456789012:url/my-lambda-url',
867+
}),
868+
});
869+
});
870+
720871
test('knows how to handle attributes of the AWS::KMS::Key resource', async () => {
721872
// GIVEN
722873
setup.setCurrentCfnStackTemplate({

0 commit comments

Comments
 (0)