Skip to content

Commit

Permalink
feat(dynamodb): support RemovalPolicy (#3028)
Browse files Browse the repository at this point in the history
Add support for RemovalPolicy on DynamoDB `Table`s, defaulting to
`RemovalPolicy.RETAIN` as the resource is inherently stateful.

Fixes #2710
  • Loading branch information
RomainMuller authored Jun 26, 2019

Verified

This commit was signed with the committer’s verified signature.
targos Michaël Zasso
1 parent 796d6bb commit a6175be
Showing 17 changed files with 295 additions and 248 deletions.
Original file line number Diff line number Diff line change
@@ -45,16 +45,17 @@ export class GlobalTable extends cdk.Construct {

// need to set this stream specification, otherwise global tables don't work
// And no way to set a default value in an interface
const stackProps: dynamodb.TableProps = {
const regionalTableProps: dynamodb.TableProps = {
...props,
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES
removalPolicy: props.removalPolicy,
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
};

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

Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@ export class GlobalTableCoordinator extends cdk.Stack {
resourceType: "Custom::DynamoGlobalTableCoordinator",
tableName: props.tableName,
},
removalPolicy: props.removalPolicy,
});
}
}
Original file line number Diff line number Diff line change
@@ -24,7 +24,8 @@
"StreamViewType": "NEW_AND_OLD_IMAGES"
},
"TableName": "integrationtest"
}
},
"DeletionPolicy": "Delete"
}
}
},
@@ -53,7 +54,8 @@
"StreamViewType": "NEW_AND_OLD_IMAGES"
},
"TableName": "integrationtest"
}
},
"DeletionPolicy": "Delete"
}
}
},
@@ -82,7 +84,8 @@
"StreamViewType": "NEW_AND_OLD_IMAGES"
},
"TableName": "integrationtest"
}
},
"DeletionPolicy": "Delete"
}
}
},
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/// !cdk-integ *
import { AttributeType } from '@aws-cdk/aws-dynamodb';
import { App } from '@aws-cdk/core';
import { App, RemovalPolicy } from '@aws-cdk/core';
import { GlobalTable } from '../lib';

const app = new App();
new GlobalTable(app, 'globdynamodbinteg', {
partitionKey: { name: 'hashKey', type: AttributeType.STRING },
tableName: 'integrationtest',
regions: [ "us-east-1", "us-east-2", "us-west-2" ]
regions: ["us-east-1", "us-east-2", "us-west-2"],
removalPolicy: RemovalPolicy.DESTROY,
});
app.synth();
10 changes: 9 additions & 1 deletion packages/@aws-cdk/aws-dynamodb/lib/table.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import appscaling = require('@aws-cdk/aws-applicationautoscaling');
import iam = require('@aws-cdk/aws-iam');
import { Aws, Construct, Lazy, Resource, Stack } from '@aws-cdk/core';
import { Aws, Construct, Lazy, RemovalPolicy, Resource, Stack } from '@aws-cdk/core';
import { CfnTable } from './dynamodb.generated';
import { EnableScalingProps, IScalableTableAttribute } from './scalable-attribute-api';
import { ScalableTableAttribute } from './scalable-table-attribute';
@@ -107,6 +107,13 @@ export interface TableOptions {
* @default undefined, streams are disabled
*/
readonly stream?: StreamViewType;

/**
* The removal policy to apply to the DynamoDB Table.
*
* @default RemovalPolicy.RETAIN
*/
readonly removalPolicy?: RemovalPolicy;
}

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

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

Original file line number Diff line number Diff line change
@@ -9,17 +9,18 @@
"KeyType": "HASH"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
},
"AttributeDefinitions": [
{
"AttributeName": "hashKey",
"AttributeType": "S"
}
]
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
}
},
"DeletionPolicy": "Delete"
},
"TableReadScalingTargetF96E9F76": {
"Type": "AWS::ApplicationAutoScaling::ScalableTarget",
@@ -94,4 +95,4 @@
}
}
}
}
}
5 changes: 3 additions & 2 deletions packages/@aws-cdk/aws-dynamodb/test/integ.autoscaling.lit.ts
Original file line number Diff line number Diff line change
@@ -6,7 +6,8 @@ const app = new cdk.App();
const stack = new cdk.Stack(app, 'aws-cdk-dynamodb');

const table = new dynamodb.Table(stack, 'Table', {
partitionKey: { name: 'hashKey', type: dynamodb.AttributeType.STRING }
partitionKey: { name: 'hashKey', type: dynamodb.AttributeType.STRING },
removalPolicy: cdk.RemovalPolicy.DESTROY,
});

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

app.synth();
app.synth();
12 changes: 8 additions & 4 deletions packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.expected.json
Original file line number Diff line number Diff line change
@@ -19,7 +19,8 @@
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
}
}
},
"DeletionPolicy": "Delete"
},
"TableWithGlobalAndLocalSecondaryIndexBC540710": {
"Type": "AWS::DynamoDB::Table",
@@ -267,7 +268,8 @@
"AttributeName": "timeToLive",
"Enabled": true
}
}
},
"DeletionPolicy": "Delete"
},
"TableWithGlobalSecondaryIndexCC8E841E": {
"Type": "AWS::DynamoDB::Table",
@@ -310,7 +312,8 @@
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
}
}
},
"DeletionPolicy": "Delete"
},
"TableWithLocalSecondaryIndex4DA3D08F": {
"Type": "AWS::DynamoDB::Table",
@@ -361,7 +364,8 @@
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
}
}
},
"DeletionPolicy": "Delete"
},
"User00B015A1": {
"Type": "AWS::IAM::User"
Original file line number Diff line number Diff line change
@@ -9,14 +9,15 @@
"KeyType": "HASH"
}
],
"BillingMode": "PAY_PER_REQUEST",
"AttributeDefinitions": [
{
"AttributeName": "hashKey",
"AttributeType": "S"
}
]
}
],
"BillingMode": "PAY_PER_REQUEST"
},
"DeletionPolicy": "Delete"
},
"TableWithGlobalAndLocalSecondaryIndexBC540710": {
"Type": "AWS::DynamoDB::Table",
@@ -31,7 +32,6 @@
"KeyType": "RANGE"
}
],
"BillingMode": "PAY_PER_REQUEST",
"AttributeDefinitions": [
{
"AttributeName": "hashKey",
@@ -54,6 +54,7 @@
"AttributeType": "N"
}
],
"BillingMode": "PAY_PER_REQUEST",
"GlobalSecondaryIndexes": [
{
"IndexName": "GSI-PartitionKeyOnly",
@@ -241,7 +242,8 @@
"AttributeName": "timeToLive",
"Enabled": true
}
}
},
"DeletionPolicy": "Delete"
},
"TableWithGlobalSecondaryIndexCC8E841E": {
"Type": "AWS::DynamoDB::Table",
@@ -277,7 +279,8 @@
}
}
]
}
},
"DeletionPolicy": "Delete"
},
"TableWithLocalSecondaryIndex4DA3D08F": {
"Type": "AWS::DynamoDB::Table",
@@ -325,7 +328,8 @@
}
}
]
}
},
"DeletionPolicy": "Delete"
}
}
}
10 changes: 7 additions & 3 deletions packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ondemand.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { App, Stack, Tag } from '@aws-cdk/core';
import { App, RemovalPolicy, Stack, Tag } from '@aws-cdk/core';
import { Attribute, AttributeType, BillingMode, ProjectionType, StreamViewType, Table } from '../lib';

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

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

tableWithGlobalAndLocalSecondaryIndex.node.applyAspect(new Tag('Environment', 'Production'));
@@ -109,6 +111,7 @@ tableWithGlobalAndLocalSecondaryIndex.addLocalSecondaryIndex({
const tableWithGlobalSecondaryIndex = new Table(stack, TABLE_WITH_GLOBAL_SECONDARY_INDEX, {
billingMode: BillingMode.PAY_PER_REQUEST,
partitionKey: TABLE_PARTITION_KEY,
removalPolicy: RemovalPolicy.DESTROY,
});
tableWithGlobalSecondaryIndex.addGlobalSecondaryIndex({
indexName: GSI_TEST_CASE_1,
@@ -119,6 +122,7 @@ const tableWithLocalSecondaryIndex = new Table(stack, TABLE_WITH_LOCAL_SECONDARY
billingMode: BillingMode.PAY_PER_REQUEST,
partitionKey: TABLE_PARTITION_KEY,
sortKey: TABLE_SORT_KEY,
removalPolicy: RemovalPolicy.DESTROY,
});

tableWithLocalSecondaryIndex.addLocalSecondaryIndex({
14 changes: 9 additions & 5 deletions packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import iam = require('@aws-cdk/aws-iam');
import { App, Stack, Tag } from '@aws-cdk/core';
import { App, RemovalPolicy, Stack, Tag } from '@aws-cdk/core';
import { Attribute, AttributeType, ProjectionType, StreamViewType, Table } from '../lib';

// CDK parameters
@@ -42,7 +42,8 @@ const app = new App();
const stack = new Stack(app, STACK_NAME);

const table = new Table(stack, TABLE, {
partitionKey: TABLE_PARTITION_KEY
partitionKey: TABLE_PARTITION_KEY,
removalPolicy: RemovalPolicy.DESTROY,
});

const tableWithGlobalAndLocalSecondaryIndex = new Table(stack, TABLE_WITH_GLOBAL_AND_LOCAL_SECONDARY_INDEX, {
@@ -51,7 +52,8 @@ const tableWithGlobalAndLocalSecondaryIndex = new Table(stack, TABLE_WITH_GLOBAL
stream: StreamViewType.KEYS_ONLY,
timeToLiveAttribute: 'timeToLive',
partitionKey: TABLE_PARTITION_KEY,
sortKey: TABLE_SORT_KEY
sortKey: TABLE_SORT_KEY,
removalPolicy: RemovalPolicy.DESTROY,
});

tableWithGlobalAndLocalSecondaryIndex.node.applyAspect(new Tag('Environment', 'Production'));
@@ -106,7 +108,8 @@ tableWithGlobalAndLocalSecondaryIndex.addLocalSecondaryIndex({
});

const tableWithGlobalSecondaryIndex = new Table(stack, TABLE_WITH_GLOBAL_SECONDARY_INDEX, {
partitionKey: TABLE_PARTITION_KEY
partitionKey: TABLE_PARTITION_KEY,
removalPolicy: RemovalPolicy.DESTROY,
});
tableWithGlobalSecondaryIndex.addGlobalSecondaryIndex({
indexName: GSI_TEST_CASE_1,
@@ -115,7 +118,8 @@ tableWithGlobalSecondaryIndex.addGlobalSecondaryIndex({

const tableWithLocalSecondaryIndex = new Table(stack, TABLE_WITH_LOCAL_SECONDARY_INDEX, {
partitionKey: TABLE_PARTITION_KEY,
sortKey: TABLE_SORT_KEY
sortKey: TABLE_SORT_KEY,
removalPolicy: RemovalPolicy.DESTROY,
});

tableWithLocalSecondaryIndex.addLocalSecondaryIndex({
Loading

0 comments on commit a6175be

Please sign in to comment.