Skip to content

Commit

Permalink
feat(redshift): relocating a cluster (#31993)
Browse files Browse the repository at this point in the history
### Issue # (if applicable)

None

### Reason for this change

AWS Redshift supports for configuring [relocation a cluster](https://docs.aws.amazon.com/redshift/latest/mgmt/managing-cluster-recovery.html) and this feature is supported by [cfn](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-availabilityzonerelocationstatus).

### Description of changes

Add `availabilityZoneRelocation` to `CusterProps`.

[Documents](https://docs.aws.amazon.com/redshift/latest/mgmt/managing-cluster-recovery.html) says that this feature is not supported for DC2 node type.

```
Relocation isn't supported on DC2 instance families of products.
```

However, this feature is only supported for RA3 node type in actual.

Example implementation:
```ts
new redshift.Cluster(stack, 'Cluster', {
  vpc: vpc,
  masterUser: {
    masterUsername: 'admin',
  },
  availabilityZoneRelocation: true,
  nodeType: redshift.NodeType.DC2_LARGE,
});
```

Result:
```sh
Failed resources:
AzRelocationClusterStack | 6:52:00 PM | CREATE_FAILED        | AWS::Redshift::Cluster                      | Cluster (ClusterEB0386A7) Resource handler returned message: "If the cluster node type isn?t RA3, availability zone relocation isn?t supported. (Service: Redshift, Status Code: 400, Request ID: 6382b593-cce5-4fe5-b4de-de1ad1c3a604)" (RequestToken: 94c999d9-7b72-19c4-9cfe-154fe6abc717, HandlerErrorCode: GeneralServiceException)
```

So I added this validation.

```ts
    if (props.availabilityZoneRelocation && !nodeType.startsWith('ra3')) {
      throw new Error(`Availability zone relocation is supported for only RA3 node types, got: ${props.nodeType}`);
    }
```

### Description of how you validated changes

Add 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 Nov 12, 2024
1 parent 338d4c2 commit b763d86
Show file tree
Hide file tree
Showing 12 changed files with 1,715 additions and 0 deletions.
24 changes: 24 additions & 0 deletions packages/@aws-cdk/aws-redshift-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,30 @@ const cluster = new Cluster(this, 'Redshift', {
});
```

## Availability Zone Relocation

By using [relocation in Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/managing-cluster-recovery.html), you allow Amazon Redshift to move a cluster to another Availability Zone (AZ) without any loss of data or changes to your applications.
This feature can be applied to both new and existing clusters.

To enable this feature, set the `availabilityZoneRelocation` property to `true`.

```ts
import * as ec2 from 'aws-cdk-lib/aws-ec2';

declare const vpc: ec2.IVpc;

const cluster = new Cluster(this, 'Redshift', {
masterUser: {
masterUsername: 'admin',
},
vpc,
nodeType: NodeType.RA3_XLPLUS,
availabilityZoneRelocation: true,
});
```

**Note**: The `availabilityZoneRelocation` property is only available for RA3 node types.

## Connecting

To control who can access the cluster, use the `.connections` attribute. Redshift Clusters have
Expand Down
14 changes: 14 additions & 0 deletions packages/@aws-cdk/aws-redshift-alpha/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,15 @@ export interface ClusterProps {
* @default - false
*/
readonly multiAz?: boolean;

/**
* Whether to enable relocation for an Amazon Redshift cluster between Availability Zones after the cluster is created.
*
* @see https://docs.aws.amazon.com/redshift/latest/mgmt/managing-cluster-recovery.html
*
* @default - false
*/
readonly availabilityZoneRelocation?: boolean;
}

/**
Expand Down Expand Up @@ -584,6 +593,10 @@ export class Cluster extends ClusterBase {
}
}

if (props.availabilityZoneRelocation && !nodeType.startsWith('ra3')) {
throw new Error(`Availability zone relocation is supported for only RA3 node types, got: ${props.nodeType}`);
}

this.cluster = new CfnCluster(this, 'Resource', {
// Basic
allowVersionUpgrade: true,
Expand Down Expand Up @@ -613,6 +626,7 @@ export class Cluster extends ClusterBase {
elasticIp: props.elasticIp,
enhancedVpcRouting: props.enhancedVpcRouting,
multiAz: props.multiAz,
availabilityZoneRelocation: props.availabilityZoneRelocation,
});

this.cluster.applyRemovalPolicy(removalPolicy, {
Expand Down
33 changes: 33 additions & 0 deletions packages/@aws-cdk/aws-redshift-alpha/test/cluster.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,39 @@ test('publicly accessible cluster', () => {
});
});

test('availability zone relocation enabled', () => {
// WHEN
new Cluster(stack, 'Redshift', {
masterUser: {
masterUsername: 'admin',
},
vpc,
availabilityZoneRelocation: true,
nodeType: NodeType.RA3_XLPLUS,
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', {
AvailabilityZoneRelocation: true,
});
});

test.each([
NodeType.DC1_8XLARGE,
NodeType.DC2_LARGE,
])('throw error when availability zone relocation is enabled for invalid node type %s', (nodeType) => {
expect(() => {
new Cluster(stack, 'Redshift', {
masterUser: {
masterUsername: 'admin',
},
vpc,
availabilityZoneRelocation: true,
nodeType,
});
}).toThrow(`Availability zone relocation is supported for only RA3 node types, got: ${nodeType}`);
});

test('imported cluster with imported security group honors allowAllOutbound', () => {
// GIVEN
const cluster = Cluster.fromClusterAttributes(stack, 'Database', {
Expand Down

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

Loading

0 comments on commit b763d86

Please sign in to comment.