diff --git a/packages/@aws-cdk/aws-dynamodb/lib/replica-handler/index.ts b/packages/@aws-cdk/aws-dynamodb/lib/replica-handler/index.ts index 814bad346ece2..1554dcc84004d 100644 --- a/packages/@aws-cdk/aws-dynamodb/lib/replica-handler/index.ts +++ b/packages/@aws-cdk/aws-dynamodb/lib/replica-handler/index.ts @@ -5,27 +5,34 @@ import { DynamoDB } from 'aws-sdk'; // eslint-disable-line import/no-extraneous- export async function onEventHandler(event: OnEventRequest): Promise { console.log('Event: %j', event); - /** - * Process only Create and Delete requests. We shouldn't receive any - * update request and in case we do there is nothing to update. - */ + const dynamodb = new DynamoDB(); + + let updateTableAction: 'Create' | 'Update' | 'Delete'; if (event.RequestType === 'Create' || event.RequestType === 'Delete') { - const dynamodb = new DynamoDB(); - - const data = await dynamodb.updateTable({ - TableName: event.ResourceProperties.TableName, - ReplicaUpdates: [ - { - [event.RequestType]: { - RegionName: event.ResourceProperties.Region, - }, - }, - ], - }).promise(); - console.log('Update table: %j', data); + updateTableAction = event.RequestType; + } else { // Update + // This can only be a table replacement so we create a replica + // in the new table. The replica for the "old" table will be + // deleted when CF issues a Delete event on the old physical + // resource id. + updateTableAction = 'Create'; } - return { PhysicalResourceId: event.ResourceProperties.Region }; + const data = await dynamodb.updateTable({ + TableName: event.ResourceProperties.TableName, + ReplicaUpdates: [ + { + [updateTableAction]: { + RegionName: event.ResourceProperties.Region, + }, + }, + ], + }).promise(); + console.log('Update table: %j', data); + + return event.RequestType === 'Create' || event.RequestType === 'Update' + ? { PhysicalResourceId: `${event.ResourceProperties.TableName}-${event.ResourceProperties.Region}` } + : {}; } export async function isCompleteHandler(event: IsCompleteRequest): Promise { diff --git a/packages/@aws-cdk/aws-dynamodb/lib/table.ts b/packages/@aws-cdk/aws-dynamodb/lib/table.ts index 1b12eef42de1f..8f36894fc5df8 100644 --- a/packages/@aws-cdk/aws-dynamodb/lib/table.ts +++ b/packages/@aws-cdk/aws-dynamodb/lib/table.ts @@ -1670,12 +1670,19 @@ interface ScalableAttributePair { */ class SourceTableAttachedPolicy extends CoreConstruct implements iam.IGrantable { public readonly grantPrincipal: iam.IPrincipal; - public readonly policy: iam.IPolicy; + public readonly policy: iam.IManagedPolicy; public constructor(sourceTable: Table, role: iam.IRole) { - super(sourceTable, `SourceTableAttachedPolicy-${Names.nodeUniqueId(role.node)}`); - - const policy = new iam.Policy(this, 'Resource', { roles: [role] }); + super(sourceTable, `SourceTableAttachedManagedPolicy-${Names.nodeUniqueId(role.node)}`); + + const policy = new iam.ManagedPolicy(this, 'Resource', { + // A CF update of the description property of a managed policy requires + // a replacement. Use the table name in the description to force a managed + // policy replacement when the table name changes. This way we preserve permissions + // to delete old replicas in case of a table replacement. + description: `DynamoDB replication managed policy for table ${sourceTable.tableName}`, + roles: [role], + }); this.policy = policy; this.grantPrincipal = new SourceTableAttachedPrincipal(role, policy); } @@ -1686,7 +1693,7 @@ class SourceTableAttachedPolicy extends CoreConstruct implements iam.IGrantable * `SourceTableAttachedPolicy` class so it can act as an `IGrantable`. */ class SourceTableAttachedPrincipal extends iam.PrincipalBase { - public constructor(private readonly role: iam.IRole, private readonly policy: iam.Policy) { + public constructor(private readonly role: iam.IRole, private readonly policy: iam.ManagedPolicy) { super(); } diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.global-replicas-provisioned.expected.json b/packages/@aws-cdk/aws-dynamodb/test/integ.global-replicas-provisioned.expected.json index 89a9c3807fc21..b4ea44f2709c4 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.global-replicas-provisioned.expected.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.global-replicas-provisioned.expected.json @@ -26,8 +26,8 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "TableSourceTableAttachedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderOnEventHandlerServiceRoleD9856B77945CD5DF": { - "Type": "AWS::IAM::Policy", + "TableSourceTableAttachedManagedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderOnEventHandlerServiceRoleD9856B771F8F2CCB": { + "Type": "AWS::IAM::ManagedPolicy", "Properties": { "PolicyDocument": { "Statement": [ @@ -93,7 +93,18 @@ ], "Version": "2012-10-17" }, - "PolicyName": "leAttachedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderOnEventHandlerServiceRoleD9856B77945CD5DF", + "Description": { + "Fn::Join": [ + "", + [ + "DynamoDB replication managed policy for table ", + { + "Ref": "TableCD117FA1" + } + ] + ] + }, + "Path": "/", "Roles": [ { "Fn::GetAtt": [ @@ -104,8 +115,8 @@ ] } }, - "TableSourceTableAttachedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRoleBE2B1C1AE3D3CF6D": { - "Type": "AWS::IAM::Policy", + "TableSourceTableAttachedManagedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRoleBE2B1C1A5DC546D2": { + "Type": "AWS::IAM::ManagedPolicy", "Properties": { "PolicyDocument": { "Statement": [ @@ -127,7 +138,18 @@ ], "Version": "2012-10-17" }, - "PolicyName": "ttachedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRoleBE2B1C1AE3D3CF6D", + "Description": { + "Fn::Join": [ + "", + [ + "DynamoDB replication managed policy for table ", + { + "Ref": "TableCD117FA1" + } + ] + ] + }, + "Path": "/", "Roles": [ { "Fn::GetAtt": [ @@ -153,8 +175,8 @@ "Region": "us-east-2" }, "DependsOn": [ - "TableSourceTableAttachedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRoleBE2B1C1AE3D3CF6D", - "TableSourceTableAttachedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderOnEventHandlerServiceRoleD9856B77945CD5DF", + "TableSourceTableAttachedManagedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRoleBE2B1C1A5DC546D2", + "TableSourceTableAttachedManagedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderOnEventHandlerServiceRoleD9856B771F8F2CCB", "TableWriteScalingTargetE5669214", "TableWriteScalingTargetTrackingD78DCCD8" ], @@ -178,8 +200,8 @@ }, "DependsOn": [ "TableReplicauseast28A15C236", - "TableSourceTableAttachedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRoleBE2B1C1AE3D3CF6D", - "TableSourceTableAttachedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderOnEventHandlerServiceRoleD9856B77945CD5DF", + "TableSourceTableAttachedManagedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRoleBE2B1C1A5DC546D2", + "TableSourceTableAttachedManagedPolicyawscdkdynamodbglobalreplicasprovisionedawscdkawsdynamodbReplicaProviderOnEventHandlerServiceRoleD9856B771F8F2CCB", "TableWriteScalingTargetE5669214", "TableWriteScalingTargetTrackingD78DCCD8" ], @@ -256,7 +278,7 @@ }, "/", { - "Ref": "AssetParameterse31d108faccc52dcd9a9d86276a05e6ad861311925fe6931eadc31d0fe17e1fdS3BucketEDAACFE7" + "Ref": "AssetParametersd56d097acd2563516c51a0e04dcf8d9bf3638678f723d5b80f95d5c240836aadS3Bucket806FEB2C" }, "/", { @@ -266,7 +288,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameterse31d108faccc52dcd9a9d86276a05e6ad861311925fe6931eadc31d0fe17e1fdS3VersionKey6FF3D50F" + "Ref": "AssetParametersd56d097acd2563516c51a0e04dcf8d9bf3638678f723d5b80f95d5c240836aadS3VersionKey81C7BC5B" } ] } @@ -279,7 +301,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameterse31d108faccc52dcd9a9d86276a05e6ad861311925fe6931eadc31d0fe17e1fdS3VersionKey6FF3D50F" + "Ref": "AssetParametersd56d097acd2563516c51a0e04dcf8d9bf3638678f723d5b80f95d5c240836aadS3VersionKey81C7BC5B" } ] } @@ -289,11 +311,11 @@ ] }, "Parameters": { - "referencetoawscdkdynamodbglobalreplicasprovisionedAssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3Bucket50997EC4Ref": { - "Ref": "AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3Bucket1C6779E0" + "referencetoawscdkdynamodbglobalreplicasprovisionedAssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3BucketD1258B42Ref": { + "Ref": "AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3BucketDEBF01E6" }, - "referencetoawscdkdynamodbglobalreplicasprovisionedAssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3VersionKey0F47C425Ref": { - "Ref": "AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3VersionKey5C1D9275" + "referencetoawscdkdynamodbglobalreplicasprovisionedAssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3VersionKey0F5C355ERef": { + "Ref": "AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3VersionKey42EBA2AE" }, "referencetoawscdkdynamodbglobalreplicasprovisionedAssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3Bucket6C51C355Ref": { "Ref": "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1" @@ -334,17 +356,17 @@ } }, "Parameters": { - "AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3Bucket1C6779E0": { + "AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3BucketDEBF01E6": { "Type": "String", - "Description": "S3 bucket for asset \"f13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714\"" + "Description": "S3 bucket for asset \"dd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776\"" }, - "AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3VersionKey5C1D9275": { + "AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3VersionKey42EBA2AE": { "Type": "String", - "Description": "S3 key for asset version \"f13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714\"" + "Description": "S3 key for asset version \"dd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776\"" }, - "AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714ArtifactHash477AAEA7": { + "AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776ArtifactHash692B4CCE": { "Type": "String", - "Description": "Artifact hash for asset \"f13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714\"" + "Description": "Artifact hash for asset \"dd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776\"" }, "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1": { "Type": "String", @@ -358,17 +380,17 @@ "Type": "String", "Description": "Artifact hash for asset \"daeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1\"" }, - "AssetParameterse31d108faccc52dcd9a9d86276a05e6ad861311925fe6931eadc31d0fe17e1fdS3BucketEDAACFE7": { + "AssetParametersd56d097acd2563516c51a0e04dcf8d9bf3638678f723d5b80f95d5c240836aadS3Bucket806FEB2C": { "Type": "String", - "Description": "S3 bucket for asset \"e31d108faccc52dcd9a9d86276a05e6ad861311925fe6931eadc31d0fe17e1fd\"" + "Description": "S3 bucket for asset \"d56d097acd2563516c51a0e04dcf8d9bf3638678f723d5b80f95d5c240836aad\"" }, - "AssetParameterse31d108faccc52dcd9a9d86276a05e6ad861311925fe6931eadc31d0fe17e1fdS3VersionKey6FF3D50F": { + "AssetParametersd56d097acd2563516c51a0e04dcf8d9bf3638678f723d5b80f95d5c240836aadS3VersionKey81C7BC5B": { "Type": "String", - "Description": "S3 key for asset version \"e31d108faccc52dcd9a9d86276a05e6ad861311925fe6931eadc31d0fe17e1fd\"" + "Description": "S3 key for asset version \"d56d097acd2563516c51a0e04dcf8d9bf3638678f723d5b80f95d5c240836aad\"" }, - "AssetParameterse31d108faccc52dcd9a9d86276a05e6ad861311925fe6931eadc31d0fe17e1fdArtifactHash898696F1": { + "AssetParametersd56d097acd2563516c51a0e04dcf8d9bf3638678f723d5b80f95d5c240836aadArtifactHashD0230F6F": { "Type": "String", - "Description": "Artifact hash for asset \"e31d108faccc52dcd9a9d86276a05e6ad861311925fe6931eadc31d0fe17e1fd\"" + "Description": "Artifact hash for asset \"d56d097acd2563516c51a0e04dcf8d9bf3638678f723d5b80f95d5c240836aad\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.global.expected.json b/packages/@aws-cdk/aws-dynamodb/test/integ.global.expected.json index a66dd3d965ed9..3896ac3a355b2 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.global.expected.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.global.expected.json @@ -41,8 +41,8 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "TableSourceTableAttachedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderOnEventHandlerServiceRole6F43DF4AA4E210EA": { - "Type": "AWS::IAM::Policy", + "TableSourceTableAttachedManagedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderOnEventHandlerServiceRole6F43DF4A23250B4C": { + "Type": "AWS::IAM::ManagedPolicy", "Properties": { "PolicyDocument": { "Statement": [ @@ -119,7 +119,18 @@ ], "Version": "2012-10-17" }, - "PolicyName": "TableSourceTableAttachedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderOnEventHandlerServiceRole6F43DF4AA4E210EA", + "Description": { + "Fn::Join": [ + "", + [ + "DynamoDB replication managed policy for table ", + { + "Ref": "TableCD117FA1" + } + ] + ] + }, + "Path": "/", "Roles": [ { "Fn::GetAtt": [ @@ -130,8 +141,8 @@ ] } }, - "TableSourceTableAttachedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRole397161288F61AAFA": { - "Type": "AWS::IAM::Policy", + "TableSourceTableAttachedManagedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRole3971612857304880": { + "Type": "AWS::IAM::ManagedPolicy", "Properties": { "PolicyDocument": { "Statement": [ @@ -164,7 +175,18 @@ ], "Version": "2012-10-17" }, - "PolicyName": "leSourceTableAttachedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRole397161288F61AAFA", + "Description": { + "Fn::Join": [ + "", + [ + "DynamoDB replication managed policy for table ", + { + "Ref": "TableCD117FA1" + } + ] + ] + }, + "Path": "/", "Roles": [ { "Fn::GetAtt": [ @@ -190,8 +212,8 @@ "Region": "eu-west-2" }, "DependsOn": [ - "TableSourceTableAttachedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRole397161288F61AAFA", - "TableSourceTableAttachedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderOnEventHandlerServiceRole6F43DF4AA4E210EA" + "TableSourceTableAttachedManagedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRole3971612857304880", + "TableSourceTableAttachedManagedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderOnEventHandlerServiceRole6F43DF4A23250B4C" ], "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -212,8 +234,8 @@ }, "DependsOn": [ "TableReplicaeuwest290D3CD3A", - "TableSourceTableAttachedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRole397161288F61AAFA", - "TableSourceTableAttachedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderOnEventHandlerServiceRole6F43DF4AA4E210EA" + "TableSourceTableAttachedManagedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderIsCompleteHandlerServiceRole3971612857304880", + "TableSourceTableAttachedManagedPolicycdkdynamodbglobal20191121awscdkawsdynamodbReplicaProviderOnEventHandlerServiceRole6F43DF4A23250B4C" ], "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -231,7 +253,7 @@ }, "/", { - "Ref": "AssetParametersf8cfc24954f0c95960d9a93888c01bf5e95802f26bfa5dc6fde5c913a1429ceaS3Bucket434BDB62" + "Ref": "AssetParametersa789639d6caa7a94b8135bc6ff3a6935f95624a9ed88014b5e7b3d340f20c3b4S3Bucket8BB0CECD" }, "/", { @@ -241,7 +263,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersf8cfc24954f0c95960d9a93888c01bf5e95802f26bfa5dc6fde5c913a1429ceaS3VersionKey01638790" + "Ref": "AssetParametersa789639d6caa7a94b8135bc6ff3a6935f95624a9ed88014b5e7b3d340f20c3b4S3VersionKeyC531296D" } ] } @@ -254,7 +276,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersf8cfc24954f0c95960d9a93888c01bf5e95802f26bfa5dc6fde5c913a1429ceaS3VersionKey01638790" + "Ref": "AssetParametersa789639d6caa7a94b8135bc6ff3a6935f95624a9ed88014b5e7b3d340f20c3b4S3VersionKeyC531296D" } ] } @@ -264,11 +286,11 @@ ] }, "Parameters": { - "referencetocdkdynamodbglobal20191121AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3Bucket71E24D5BRef": { - "Ref": "AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3Bucket1C6779E0" + "referencetocdkdynamodbglobal20191121AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3Bucket06999F76Ref": { + "Ref": "AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3BucketDEBF01E6" }, - "referencetocdkdynamodbglobal20191121AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3VersionKeyD88E8BACRef": { - "Ref": "AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3VersionKey5C1D9275" + "referencetocdkdynamodbglobal20191121AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3VersionKey3D988AD7Ref": { + "Ref": "AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3VersionKey42EBA2AE" }, "referencetocdkdynamodbglobal20191121AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketC7F3A147Ref": { "Ref": "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1" @@ -283,17 +305,17 @@ } }, "Parameters": { - "AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3Bucket1C6779E0": { + "AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3BucketDEBF01E6": { "Type": "String", - "Description": "S3 bucket for asset \"f13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714\"" + "Description": "S3 bucket for asset \"dd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776\"" }, - "AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714S3VersionKey5C1D9275": { + "AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776S3VersionKey42EBA2AE": { "Type": "String", - "Description": "S3 key for asset version \"f13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714\"" + "Description": "S3 key for asset version \"dd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776\"" }, - "AssetParametersf13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714ArtifactHash477AAEA7": { + "AssetParametersdd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776ArtifactHash692B4CCE": { "Type": "String", - "Description": "Artifact hash for asset \"f13d472270faaa08099009152a8848a0e7434b14773f3c3f94acca6f6c3ae714\"" + "Description": "Artifact hash for asset \"dd0a4ac30ffa331e472caec08a7784ac440d122a6f924b1bea7d48dc85f8f776\"" }, "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1": { "Type": "String", @@ -307,17 +329,17 @@ "Type": "String", "Description": "Artifact hash for asset \"daeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1\"" }, - "AssetParametersf8cfc24954f0c95960d9a93888c01bf5e95802f26bfa5dc6fde5c913a1429ceaS3Bucket434BDB62": { + "AssetParametersa789639d6caa7a94b8135bc6ff3a6935f95624a9ed88014b5e7b3d340f20c3b4S3Bucket8BB0CECD": { "Type": "String", - "Description": "S3 bucket for asset \"f8cfc24954f0c95960d9a93888c01bf5e95802f26bfa5dc6fde5c913a1429cea\"" + "Description": "S3 bucket for asset \"a789639d6caa7a94b8135bc6ff3a6935f95624a9ed88014b5e7b3d340f20c3b4\"" }, - "AssetParametersf8cfc24954f0c95960d9a93888c01bf5e95802f26bfa5dc6fde5c913a1429ceaS3VersionKey01638790": { + "AssetParametersa789639d6caa7a94b8135bc6ff3a6935f95624a9ed88014b5e7b3d340f20c3b4S3VersionKeyC531296D": { "Type": "String", - "Description": "S3 key for asset version \"f8cfc24954f0c95960d9a93888c01bf5e95802f26bfa5dc6fde5c913a1429cea\"" + "Description": "S3 key for asset version \"a789639d6caa7a94b8135bc6ff3a6935f95624a9ed88014b5e7b3d340f20c3b4\"" }, - "AssetParametersf8cfc24954f0c95960d9a93888c01bf5e95802f26bfa5dc6fde5c913a1429ceaArtifactHashD0E61C22": { + "AssetParametersa789639d6caa7a94b8135bc6ff3a6935f95624a9ed88014b5e7b3d340f20c3b4ArtifactHash9D92B407": { "Type": "String", - "Description": "Artifact hash for asset \"f8cfc24954f0c95960d9a93888c01bf5e95802f26bfa5dc6fde5c913a1429cea\"" + "Description": "Artifact hash for asset \"a789639d6caa7a94b8135bc6ff3a6935f95624a9ed88014b5e7b3d340f20c3b4\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/replica-provider.test.ts b/packages/@aws-cdk/aws-dynamodb/test/replica-provider.test.ts index 3a1d97bd4b345..4b5acef3d15cb 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/replica-provider.test.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/replica-provider.test.ts @@ -54,25 +54,62 @@ test('on event', async () => { }); expect(data).toEqual({ - PhysicalResourceId: 'eu-west-2', + PhysicalResourceId: 'my-table-eu-west-2', }); }); -test('on event does not call updateTable for Update requests', async () => { +test('on event calls updateTable with Create for Update requests with table replacement', async () => { const updateTableMock = sinon.fake.resolves({}); AWS.mock('DynamoDB', 'updateTable', updateTableMock); const data = await onEventHandler({ ...createEvent, + OldResourceProperties: { + TableName: 'my-old-table', + }, RequestType: 'Update', }); - sinon.assert.notCalled(updateTableMock); + sinon.assert.calledWith(updateTableMock, { + TableName: 'my-table', + ReplicaUpdates: [ + { + Create: { + RegionName: 'eu-west-2', + }, + }, + ], + }); expect(data).toEqual({ - PhysicalResourceId: 'eu-west-2', + PhysicalResourceId: 'my-table-eu-west-2', + }); +}); + +test('on event calls updateTable with Delete', async () => { + const updateTableMock = sinon.fake.resolves({}); + + AWS.mock('DynamoDB', 'updateTable', updateTableMock); + + const data = await onEventHandler({ + ...createEvent, + RequestType: 'Delete', + }); + + sinon.assert.calledWith(updateTableMock, { + TableName: 'my-table', + ReplicaUpdates: [ + { + Delete: { + RegionName: 'eu-west-2', + }, + }, + ], }); + + // Physical resource id never changed on Delete + expect(data).toEqual({}); }); test('is complete for create returns false without replicas', async () => {