Skip to content

Commit

Permalink
feat(redshift): multi AZ cluster (#29976)
Browse files Browse the repository at this point in the history
### Issue # (if applicable)

Closes #<issue number here>.

### Reason for this change

AWS CDK cannot configure Redshift multi-AZ cluster.

### Description of changes

Add `multiAz` to `clusterProps`.

### Description of how you validated changes

I've added both unit and integ tests.

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
badmintoncryer authored May 15, 2024
1 parent b0975e4 commit a53517c
Show file tree
Hide file tree
Showing 12 changed files with 2,502 additions and 2 deletions.
22 changes: 22 additions & 0 deletions packages/@aws-cdk/aws-redshift-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,28 @@ const cluster = new Cluster(this, 'Redshift', {
cluster.addIamRole(role);
```

## Multi-AZ

Amazon Redshift supports [multiple Availability Zones (Multi-AZ) deployments]((https://docs.aws.amazon.com/redshift/latest/mgmt/managing-cluster-multi-az.html)) for provisioned RA3 clusters.
By using Multi-AZ deployments, your Amazon Redshift data warehouse can continue operating in failure scenarios when an unexpected event happens in an Availability Zone.

To create a Multi-AZ cluster, set the `multiAz` property to `true` when creating the cluster.

```ts
declare const vpc: ec2.IVpc;

new redshift.Cluster(stack, 'Cluster', {
masterUser: {
masterUsername: 'admin',
},
vpc, // 3 AZs are required for Multi-AZ
nodeType: redshift.NodeType.RA3_XLPLUS, // must be RA3 node type
clusterType: redshift.ClusterType.MULTI_NODE, // must be MULTI_NODE
numberOfNodes: 2, // must be 2 or more
multiAz: true,
});
```

## Resizing

As your data warehousing needs change, it's possible to resize your Redshift cluster. If the cluster was deployed via CDK,
Expand Down
21 changes: 20 additions & 1 deletion packages/@aws-cdk/aws-redshift-alpha/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,13 @@ export interface ClusterProps {
* @default - false
*/
readonly enhancedVpcRouting?: boolean;

/**
* Indicating whether Amazon Redshift should deploy the cluster in two Availability Zones.
*
* @default - false
*/
readonly multiAz?: boolean;
}

/**
Expand Down Expand Up @@ -558,6 +565,17 @@ export class Cluster extends ClusterBase {
);
}

const nodeType = props.nodeType || NodeType.DC2_LARGE;

if (props.multiAz) {
if (!nodeType.startsWith('ra3')) {
throw new Error(`Multi-AZ cluster is only supported for RA3 node types, got: ${props.nodeType}`);
}
if (clusterType === ClusterType.SINGLE_NODE) {
throw new Error('Multi-AZ cluster is not supported for `clusterType` single-node');
}
}

this.cluster = new CfnCluster(this, 'Resource', {
// Basic
allowVersionUpgrade: true,
Expand All @@ -574,7 +592,7 @@ export class Cluster extends ClusterBase {
?? props.masterUser.masterPassword?.unsafeUnwrap()
?? 'default',
preferredMaintenanceWindow: props.preferredMaintenanceWindow,
nodeType: props.nodeType || NodeType.DC2_LARGE,
nodeType,
numberOfNodes: nodeCount,
loggingProperties,
iamRoles: Lazy.list({ produce: () => this.roles.map(role => role.roleArn) }, { omitEmpty: true }),
Expand All @@ -586,6 +604,7 @@ export class Cluster extends ClusterBase {
classic: props.classicResizing,
elasticIp: props.elasticIp,
enhancedVpcRouting: props.enhancedVpcRouting,
multiAz: props.multiAz,
});

this.cluster.applyRemovalPolicy(removalPolicy, {
Expand Down
63 changes: 62 additions & 1 deletion packages/@aws-cdk/aws-redshift-alpha/test/cluster.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as iam from 'aws-cdk-lib/aws-iam';
import * as kms from 'aws-cdk-lib/aws-kms';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as cdk from 'aws-cdk-lib';
import { Cluster, ClusterParameterGroup, ClusterSubnetGroup, ClusterType } from '../lib';
import { Cluster, ClusterParameterGroup, ClusterSubnetGroup, ClusterType, NodeType } from '../lib';
import { CfnCluster } from 'aws-cdk-lib/aws-redshift';

let stack: cdk.Stack;
Expand Down Expand Up @@ -614,6 +614,67 @@ test('elastic ip address', () => {
});
});

describe('multi AZ cluster', () => {
test('create a multi AZ cluster', () => {
// WHEN
new Cluster(stack, 'Redshift', {
masterUser: {
masterUsername: 'admin',
masterPassword: cdk.SecretValue.unsafePlainText('tooshort'),
},
vpc,
nodeType: NodeType.RA3_XLPLUS,
multiAz: true,
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', {
AllowVersionUpgrade: true,
MasterUsername: 'admin',
MasterUserPassword: 'tooshort',
ClusterType: 'multi-node',
AutomatedSnapshotRetentionPeriod: 1,
Encrypted: true,
NumberOfNodes: 2,
NodeType: 'ra3.xlplus',
DBName: 'default_db',
PubliclyAccessible: false,
ClusterSubnetGroupName: { Ref: 'RedshiftSubnetsDFE70E0A' },
VpcSecurityGroupIds: [
{ 'Fn::GetAtt': ['RedshiftSecurityGroup796D74A7', 'GroupId'] },
],
MultiAZ: true,
});
});

test('throw error for invalid node type', () => {
expect(() => {
new Cluster(stack, 'Redshift', {
masterUser: {
masterUsername: 'admin',
},
vpc,
nodeType: NodeType.DS2_XLARGE,
multiAz: true,
});
}).toThrow('Multi-AZ cluster is only supported for RA3 node types, got: ds2.xlarge');
});

test('throw error for single node cluster', () => {
expect(() => {
new Cluster(stack, 'Redshift', {
masterUser: {
masterUsername: 'admin',
},
vpc,
nodeType: NodeType.RA3_XLPLUS,
multiAz: true,
clusterType: ClusterType.SINGLE_NODE,
});
}).toThrow('Multi-AZ cluster is not supported for `clusterType` single-node');
});
});

describe('reboot for Parameter Changes', () => {
test('throw error for cluster without parameter group', () => {
// Given
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a53517c

Please sign in to comment.