Skip to content

Commit a6175be

Browse files
authored
feat(dynamodb): support RemovalPolicy (#3028)
Add support for RemovalPolicy on DynamoDB `Table`s, defaulting to `RemovalPolicy.RETAIN` as the resource is inherently stateful. Fixes #2710
1 parent 796d6bb commit a6175be

17 files changed

+295
-248
lines changed

packages/@aws-cdk/aws-dynamodb-global/lib/aws-dynamodb-global.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,17 @@ export class GlobalTable extends cdk.Construct {
4545

4646
// need to set this stream specification, otherwise global tables don't work
4747
// And no way to set a default value in an interface
48-
const stackProps: dynamodb.TableProps = {
48+
const regionalTableProps: dynamodb.TableProps = {
4949
...props,
50-
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES
50+
removalPolicy: props.removalPolicy,
51+
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
5152
};
5253

5354
// here we loop through the configured regions.
5455
// in each region we'll deploy a separate stack with a DynamoDB Table with identical properties in the individual stacks
5556
for (const reg of props.regions) {
5657
const regionalStack = new cdk.Stack(this, id + "-" + reg, { env: { region: reg } });
57-
const regionalTable = new dynamodb.Table(regionalStack, id + '-GlobalTable-' + reg, stackProps);
58+
const regionalTable = new dynamodb.Table(regionalStack, `${id}-GlobalTable-${reg}`, regionalTableProps);
5859
this._regionalTables.push(regionalTable);
5960
}
6061

packages/@aws-cdk/aws-dynamodb-global/lib/global-table-coordinator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export class GlobalTableCoordinator extends cdk.Stack {
3030
resourceType: "Custom::DynamoGlobalTableCoordinator",
3131
tableName: props.tableName,
3232
},
33+
removalPolicy: props.removalPolicy,
3334
});
3435
}
3536
}

packages/@aws-cdk/aws-dynamodb-global/test/integ.dynamodb.global.expected.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
"StreamViewType": "NEW_AND_OLD_IMAGES"
2525
},
2626
"TableName": "integrationtest"
27-
}
27+
},
28+
"DeletionPolicy": "Delete"
2829
}
2930
}
3031
},
@@ -53,7 +54,8 @@
5354
"StreamViewType": "NEW_AND_OLD_IMAGES"
5455
},
5556
"TableName": "integrationtest"
56-
}
57+
},
58+
"DeletionPolicy": "Delete"
5759
}
5860
}
5961
},
@@ -82,7 +84,8 @@
8284
"StreamViewType": "NEW_AND_OLD_IMAGES"
8385
},
8486
"TableName": "integrationtest"
85-
}
87+
},
88+
"DeletionPolicy": "Delete"
8689
}
8790
}
8891
},
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/// !cdk-integ *
22
import { AttributeType } from '@aws-cdk/aws-dynamodb';
3-
import { App } from '@aws-cdk/core';
3+
import { App, RemovalPolicy } from '@aws-cdk/core';
44
import { GlobalTable } from '../lib';
55

66
const app = new App();
77
new GlobalTable(app, 'globdynamodbinteg', {
88
partitionKey: { name: 'hashKey', type: AttributeType.STRING },
99
tableName: 'integrationtest',
10-
regions: [ "us-east-1", "us-east-2", "us-west-2" ]
10+
regions: ["us-east-1", "us-east-2", "us-west-2"],
11+
removalPolicy: RemovalPolicy.DESTROY,
1112
});
1213
app.synth();

packages/@aws-cdk/aws-dynamodb/lib/table.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import appscaling = require('@aws-cdk/aws-applicationautoscaling');
22
import iam = require('@aws-cdk/aws-iam');
3-
import { Aws, Construct, Lazy, Resource, Stack } from '@aws-cdk/core';
3+
import { Aws, Construct, Lazy, RemovalPolicy, Resource, Stack } from '@aws-cdk/core';
44
import { CfnTable } from './dynamodb.generated';
55
import { EnableScalingProps, IScalableTableAttribute } from './scalable-attribute-api';
66
import { ScalableTableAttribute } from './scalable-table-attribute';
@@ -107,6 +107,13 @@ export interface TableOptions {
107107
* @default undefined, streams are disabled
108108
*/
109109
readonly stream?: StreamViewType;
110+
111+
/**
112+
* The removal policy to apply to the DynamoDB Table.
113+
*
114+
* @default RemovalPolicy.RETAIN
115+
*/
116+
readonly removalPolicy?: RemovalPolicy;
110117
}
111118

112119
export interface TableProps extends TableOptions {
@@ -247,6 +254,7 @@ export class Table extends Resource {
247254
streamSpecification: props.stream ? { streamViewType: props.stream } : undefined,
248255
timeToLiveSpecification: props.timeToLiveAttribute ? { attributeName: props.timeToLiveAttribute, enabled: true } : undefined
249256
});
257+
this.table.applyRemovalPolicy(props.removalPolicy);
250258

251259
if (props.tableName) { this.node.addMetadata('aws:cdk:hasPhysicalName', props.tableName); }
252260

packages/@aws-cdk/aws-dynamodb/test/integ.autoscaling.lit.expected.json

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@
99
"KeyType": "HASH"
1010
}
1111
],
12-
"ProvisionedThroughput": {
13-
"ReadCapacityUnits": 5,
14-
"WriteCapacityUnits": 5
15-
},
1612
"AttributeDefinitions": [
1713
{
1814
"AttributeName": "hashKey",
1915
"AttributeType": "S"
2016
}
21-
]
22-
}
17+
],
18+
"ProvisionedThroughput": {
19+
"ReadCapacityUnits": 5,
20+
"WriteCapacityUnits": 5
21+
}
22+
},
23+
"DeletionPolicy": "Delete"
2324
},
2425
"TableReadScalingTargetF96E9F76": {
2526
"Type": "AWS::ApplicationAutoScaling::ScalableTarget",
@@ -94,4 +95,4 @@
9495
}
9596
}
9697
}
97-
}
98+
}

packages/@aws-cdk/aws-dynamodb/test/integ.autoscaling.lit.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ const app = new cdk.App();
66
const stack = new cdk.Stack(app, 'aws-cdk-dynamodb');
77

88
const table = new dynamodb.Table(stack, 'Table', {
9-
partitionKey: { name: 'hashKey', type: dynamodb.AttributeType.STRING }
9+
partitionKey: { name: 'hashKey', type: dynamodb.AttributeType.STRING },
10+
removalPolicy: cdk.RemovalPolicy.DESTROY,
1011
});
1112

1213
/// !show
@@ -27,4 +28,4 @@ readScaling.scaleOnSchedule('ScaleDownAtNight', {
2728
});
2829
/// !hide
2930

30-
app.synth();
31+
app.synth();

packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.expected.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"ReadCapacityUnits": 5,
2020
"WriteCapacityUnits": 5
2121
}
22-
}
22+
},
23+
"DeletionPolicy": "Delete"
2324
},
2425
"TableWithGlobalAndLocalSecondaryIndexBC540710": {
2526
"Type": "AWS::DynamoDB::Table",
@@ -267,7 +268,8 @@
267268
"AttributeName": "timeToLive",
268269
"Enabled": true
269270
}
270-
}
271+
},
272+
"DeletionPolicy": "Delete"
271273
},
272274
"TableWithGlobalSecondaryIndexCC8E841E": {
273275
"Type": "AWS::DynamoDB::Table",
@@ -310,7 +312,8 @@
310312
"ReadCapacityUnits": 5,
311313
"WriteCapacityUnits": 5
312314
}
313-
}
315+
},
316+
"DeletionPolicy": "Delete"
314317
},
315318
"TableWithLocalSecondaryIndex4DA3D08F": {
316319
"Type": "AWS::DynamoDB::Table",
@@ -361,7 +364,8 @@
361364
"ReadCapacityUnits": 5,
362365
"WriteCapacityUnits": 5
363366
}
364-
}
367+
},
368+
"DeletionPolicy": "Delete"
365369
},
366370
"User00B015A1": {
367371
"Type": "AWS::IAM::User"

packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.expected.json

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
"KeyType": "HASH"
1010
}
1111
],
12-
"BillingMode": "PAY_PER_REQUEST",
1312
"AttributeDefinitions": [
1413
{
1514
"AttributeName": "hashKey",
1615
"AttributeType": "S"
1716
}
18-
]
19-
}
17+
],
18+
"BillingMode": "PAY_PER_REQUEST"
19+
},
20+
"DeletionPolicy": "Delete"
2021
},
2122
"TableWithGlobalAndLocalSecondaryIndexBC540710": {
2223
"Type": "AWS::DynamoDB::Table",
@@ -31,7 +32,6 @@
3132
"KeyType": "RANGE"
3233
}
3334
],
34-
"BillingMode": "PAY_PER_REQUEST",
3535
"AttributeDefinitions": [
3636
{
3737
"AttributeName": "hashKey",
@@ -54,6 +54,7 @@
5454
"AttributeType": "N"
5555
}
5656
],
57+
"BillingMode": "PAY_PER_REQUEST",
5758
"GlobalSecondaryIndexes": [
5859
{
5960
"IndexName": "GSI-PartitionKeyOnly",
@@ -241,7 +242,8 @@
241242
"AttributeName": "timeToLive",
242243
"Enabled": true
243244
}
244-
}
245+
},
246+
"DeletionPolicy": "Delete"
245247
},
246248
"TableWithGlobalSecondaryIndexCC8E841E": {
247249
"Type": "AWS::DynamoDB::Table",
@@ -277,7 +279,8 @@
277279
}
278280
}
279281
]
280-
}
282+
},
283+
"DeletionPolicy": "Delete"
281284
},
282285
"TableWithLocalSecondaryIndex4DA3D08F": {
283286
"Type": "AWS::DynamoDB::Table",
@@ -325,7 +328,8 @@
325328
}
326329
}
327330
]
328-
}
331+
},
332+
"DeletionPolicy": "Delete"
329333
}
330334
}
331335
}

packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { App, Stack, Tag } from '@aws-cdk/core';
1+
import { App, RemovalPolicy, Stack, Tag } from '@aws-cdk/core';
22
import { Attribute, AttributeType, BillingMode, ProjectionType, StreamViewType, Table } from '../lib';
33

44
// CDK parameters
@@ -43,7 +43,8 @@ const stack = new Stack(app, STACK_NAME);
4343
// Provisioned tables
4444
new Table(stack, TABLE, {
4545
billingMode: BillingMode.PAY_PER_REQUEST,
46-
partitionKey: TABLE_PARTITION_KEY
46+
partitionKey: TABLE_PARTITION_KEY,
47+
removalPolicy: RemovalPolicy.DESTROY,
4748
});
4849

4950
const tableWithGlobalAndLocalSecondaryIndex = new Table(stack, TABLE_WITH_GLOBAL_AND_LOCAL_SECONDARY_INDEX, {
@@ -53,7 +54,8 @@ const tableWithGlobalAndLocalSecondaryIndex = new Table(stack, TABLE_WITH_GLOBAL
5354
billingMode: BillingMode.PAY_PER_REQUEST,
5455
timeToLiveAttribute: 'timeToLive',
5556
partitionKey: TABLE_PARTITION_KEY,
56-
sortKey: TABLE_SORT_KEY
57+
sortKey: TABLE_SORT_KEY,
58+
removalPolicy: RemovalPolicy.DESTROY,
5759
});
5860

5961
tableWithGlobalAndLocalSecondaryIndex.node.applyAspect(new Tag('Environment', 'Production'));
@@ -109,6 +111,7 @@ tableWithGlobalAndLocalSecondaryIndex.addLocalSecondaryIndex({
109111
const tableWithGlobalSecondaryIndex = new Table(stack, TABLE_WITH_GLOBAL_SECONDARY_INDEX, {
110112
billingMode: BillingMode.PAY_PER_REQUEST,
111113
partitionKey: TABLE_PARTITION_KEY,
114+
removalPolicy: RemovalPolicy.DESTROY,
112115
});
113116
tableWithGlobalSecondaryIndex.addGlobalSecondaryIndex({
114117
indexName: GSI_TEST_CASE_1,
@@ -119,6 +122,7 @@ const tableWithLocalSecondaryIndex = new Table(stack, TABLE_WITH_LOCAL_SECONDARY
119122
billingMode: BillingMode.PAY_PER_REQUEST,
120123
partitionKey: TABLE_PARTITION_KEY,
121124
sortKey: TABLE_SORT_KEY,
125+
removalPolicy: RemovalPolicy.DESTROY,
122126
});
123127

124128
tableWithLocalSecondaryIndex.addLocalSecondaryIndex({

0 commit comments

Comments
 (0)