diff --git a/packages/@aws-cdk/aws-redshift/lib/cluster.ts b/packages/@aws-cdk/aws-redshift/lib/cluster.ts index ab86540d3d7b3..3a61f3ad93afe 100644 --- a/packages/@aws-cdk/aws-redshift/lib/cluster.ts +++ b/packages/@aws-cdk/aws-redshift/lib/cluster.ts @@ -322,6 +322,19 @@ export interface ClusterProps { * @default false */ readonly publiclyAccessible?: boolean + + /** + * If this flag is set, the cluster resizing type will be set to classic. + * When resizing a cluster, classic resizing will always provision a new cluster and transfer the data there. + * + * Classic resize takes more time to complete, but it can be useful in cases where the change in node count or + * the node type to migrate to doesn't fall within the bounds for elastic resize. + * + * @see https://docs.aws.amazon.com/redshift/latest/mgmt/managing-cluster-operations.html#elastic-resize + * + * @default - Elastic resize type + */ + readonly classicResizing?: boolean } /** @@ -485,6 +498,7 @@ export class Cluster extends ClusterBase { // Encryption kmsKeyId: props.encryptionKey?.keyId, encrypted: props.encrypted ?? true, + classic: props.classicResizing, }); cluster.applyRemovalPolicy(removalPolicy, { diff --git a/packages/@aws-cdk/aws-redshift/test/cluster.test.ts b/packages/@aws-cdk/aws-redshift/test/cluster.test.ts index 6db5f18ade684..80a03cb7ac207 100644 --- a/packages/@aws-cdk/aws-redshift/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-redshift/test/cluster.test.ts @@ -422,6 +422,73 @@ test('default child returns a CfnCluster', () => { expect(cluster.node.defaultChild).toBeInstanceOf(CfnCluster); }); +test.each([ + ['elastic', false], + ['classic', true], +])('resize type (%s)', (_, classicResizing) => { + // WHEN + new Cluster(stack, 'Redshift', { + masterUser: { + masterUsername: 'admin', + masterPassword: cdk.SecretValue.unsafePlainText('tooshort'), + }, + classicResizing, + vpc, + }); + + // THEN + Template.fromStack(stack).hasResource('AWS::Redshift::Cluster', { + Properties: { + AllowVersionUpgrade: true, + MasterUsername: 'admin', + MasterUserPassword: 'tooshort', + ClusterType: 'multi-node', + AutomatedSnapshotRetentionPeriod: 1, + Encrypted: true, + NumberOfNodes: 2, + NodeType: 'dc2.large', + DBName: 'default_db', + PubliclyAccessible: false, + ClusterSubnetGroupName: { Ref: 'RedshiftSubnetsDFE70E0A' }, + VpcSecurityGroupIds: [{ 'Fn::GetAtt': ['RedshiftSecurityGroup796D74A7', 'GroupId'] }], + Classic: classicResizing, + }, + DeletionPolicy: 'Retain', + UpdateReplacePolicy: 'Retain', + }); +}); + +test('resize type not set', () => { + // WHEN + new Cluster(stack, 'Redshift', { + masterUser: { + masterUsername: 'admin', + masterPassword: cdk.SecretValue.unsafePlainText('tooshort'), + }, + vpc, + }); + + // THEN + Template.fromStack(stack).hasResource('AWS::Redshift::Cluster', { + Properties: { + AllowVersionUpgrade: true, + MasterUsername: 'admin', + MasterUserPassword: 'tooshort', + ClusterType: 'multi-node', + AutomatedSnapshotRetentionPeriod: 1, + Encrypted: true, + NumberOfNodes: 2, + NodeType: 'dc2.large', + DBName: 'default_db', + PubliclyAccessible: false, + ClusterSubnetGroupName: { Ref: 'RedshiftSubnetsDFE70E0A' }, + VpcSecurityGroupIds: [{ 'Fn::GetAtt': ['RedshiftSecurityGroup796D74A7', 'GroupId'] }], + }, + DeletionPolicy: 'Retain', + UpdateReplacePolicy: 'Retain', + }); +}); + function testStack() { const newTestStack = new cdk.Stack(undefined, undefined, { env: { account: '12345', region: 'us-test-1' } }); newTestStack.node.setContext('availability-zones:12345:us-test-1', ['us-test-1a', 'us-test-1b']);