Skip to content

Commit 40835a0

Browse files
feat(redshift): execute resource action (#31995)
### Issue # (if applicable) None ### Reason for this change We can perform various Redshift operation by specifying `ResourceAction` prop but AWS CDK cannot do this. <https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-cluster.html#cfn-redshift-cluster-resourceaction> ### Description of changes - Define `ResourceAction` enum - Add `resourceAction` prop to `ClusterProps` ### 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*
1 parent 64a0e2c commit 40835a0

12 files changed

+1749
-1
lines changed

Diff for: packages/@aws-cdk/aws-redshift-alpha/README.md

+42
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,48 @@ cluster.addToParameterGroup('enable_user_activity_logging', 'true');
472472
cluster.enableRebootForParameterChanges()
473473
```
474474

475+
## Resource Action
476+
477+
You can perform various actions on the Redshift resource by specifying the `resourceAction` property,
478+
including [pausing and resuming the cluster](https://docs.aws.amazon.com/redshift/latest/mgmt/rs-mgmt-pause-resume-cluster.html), as well as initiating [failover for Multi-AZ clusters](https://docs.aws.amazon.com/redshift/latest/mgmt/test-cluster-multi-az.html).
479+
480+
```ts
481+
import * as ec2 from 'aws-cdk-lib/aws-ec2';
482+
import { ResourceAction } from '@aws-cdk/aws-redshift-alpha';
483+
484+
declare const vpc: ec2.IVpc;
485+
486+
// Pause the cluster
487+
new Cluster(this, 'PausedCluster', {
488+
masterUser: {
489+
masterUsername: 'admin',
490+
},
491+
vpc,
492+
resourceAction: ResourceAction.PAUSE,
493+
});
494+
495+
// Resume the cluster
496+
new Cluster(this, 'ResumedCluster', {
497+
masterUser: {
498+
masterUsername: 'admin',
499+
},
500+
vpc,
501+
resourceAction: ResourceAction.RESUME,
502+
});
503+
504+
// Failover the cluster
505+
new Cluster(this, 'FailOverCluster', {
506+
masterUser: {
507+
masterUsername: 'admin',
508+
},
509+
// VPC must have 3 AZs for the cluster which executes failover action
510+
vpc,
511+
// Must be a multi-AZ cluster to failover
512+
multiAz: true,
513+
resourceAction: ResourceAction.FAILOVER_PRIMARY_COMPUTE,
514+
});
515+
```
516+
475517
## Elastic IP
476518

477519
If you configure your cluster to be publicly accessible, you can optionally select an *elastic IP address* to use for the external IP address. An elastic IP address is a static IP address that is associated with your AWS account. You can use an elastic IP address to connect to your cluster from outside the VPC. An elastic IP address gives you the ability to change your underlying configuration without affecting the IP address that clients use to connect to your cluster. This approach can be helpful for situations such as recovery after a failure.

Diff for: packages/@aws-cdk/aws-redshift-alpha/lib/cluster.ts

+33
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,28 @@ export enum ClusterType {
8080
MULTI_NODE = 'multi-node',
8181
}
8282

83+
/**
84+
* The Amazon Redshift operation
85+
*/
86+
export enum ResourceAction {
87+
/**
88+
* Pause the cluster
89+
*/
90+
PAUSE_CLUSTER = 'pause-cluster',
91+
92+
/**
93+
* Resume the cluster
94+
*/
95+
RESUME_CLUSTER = 'resume-cluster',
96+
97+
/**
98+
* Failing over to the other availability zone
99+
*
100+
* @see https://docs.aws.amazon.com/redshift/latest/mgmt/test-cluster-multi-az.html
101+
*/
102+
FAILOVER_PRIMARY_COMPUTE = 'failover-primary-compute',
103+
}
104+
83105
/**
84106
* Username and password combination
85107
*/
@@ -400,6 +422,13 @@ export interface ClusterProps {
400422
*/
401423
readonly multiAz?: boolean;
402424

425+
/**
426+
* The Amazon Redshift operation to be performed.
427+
*
428+
* @default - no operation
429+
*/
430+
readonly resourceAction?: ResourceAction;
431+
403432
/**
404433
* Whether to enable relocation for an Amazon Redshift cluster between Availability Zones after the cluster is created.
405434
*
@@ -593,6 +622,9 @@ export class Cluster extends ClusterBase {
593622
}
594623
}
595624

625+
if (props.resourceAction === ResourceAction.FAILOVER_PRIMARY_COMPUTE && !props.multiAz) {
626+
throw new Error('ResourceAction.FAILOVER_PRIMARY_COMPUTE can only be used with multi-AZ clusters.');
627+
};
596628
if (props.availabilityZoneRelocation && !nodeType.startsWith('ra3')) {
597629
throw new Error(`Availability zone relocation is supported for only RA3 node types, got: ${props.nodeType}`);
598630
}
@@ -626,6 +658,7 @@ export class Cluster extends ClusterBase {
626658
elasticIp: props.elasticIp,
627659
enhancedVpcRouting: props.enhancedVpcRouting,
628660
multiAz: props.multiAz,
661+
resourceAction: props.resourceAction,
629662
availabilityZoneRelocation: props.availabilityZoneRelocation,
630663
});
631664

Diff for: packages/@aws-cdk/aws-redshift-alpha/test/cluster.test.ts

+31-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as iam from 'aws-cdk-lib/aws-iam';
44
import * as kms from 'aws-cdk-lib/aws-kms';
55
import * as s3 from 'aws-cdk-lib/aws-s3';
66
import * as cdk from 'aws-cdk-lib';
7-
import { Cluster, ClusterParameterGroup, ClusterSubnetGroup, ClusterType, NodeType } from '../lib';
7+
import { Cluster, ClusterParameterGroup, ClusterSubnetGroup, ClusterType, NodeType, ResourceAction } from '../lib';
88
import { CfnCluster } from 'aws-cdk-lib/aws-redshift';
99

1010
let stack: cdk.Stack;
@@ -512,6 +512,36 @@ test('can create a cluster with logging enabled', () => {
512512
});
513513
});
514514

515+
test.each([
516+
ResourceAction.PAUSE_CLUSTER,
517+
ResourceAction.RESUME_CLUSTER,
518+
ResourceAction.FAILOVER_PRIMARY_COMPUTE,
519+
])('specify resource action %s', (resourceAction) => {
520+
// WHEN
521+
new Cluster(stack, 'Redshift', {
522+
masterUser: {
523+
masterUsername: 'admin',
524+
},
525+
vpc,
526+
resourceAction,
527+
nodeType: NodeType.RA3_XLPLUS,
528+
multiAz: true,
529+
});
530+
});
531+
532+
test.each([false, undefined])('throw error for failover primary compute action with single AZ cluster', (multiAz) => {
533+
expect(() => {
534+
new Cluster(stack, 'Redshift', {
535+
masterUser: {
536+
masterUsername: 'admin',
537+
},
538+
vpc,
539+
multiAz,
540+
resourceAction: ResourceAction.FAILOVER_PRIMARY_COMPUTE,
541+
});
542+
}).toThrow('ResourceAction.FAILOVER_PRIMARY_COMPUTE can only be used with multi-AZ clusters.');
543+
});
544+
515545
test('throws when trying to add rotation to a cluster without secret', () => {
516546
// WHEN
517547
const cluster = new Cluster(stack, 'Redshift', {

Diff for: packages/@aws-cdk/aws-redshift-alpha/test/integ.cluster-resource-action.js.snapshot/ResourceActionIntegDefaultTestDeployAssert086BABC4.assets.json

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: packages/@aws-cdk/aws-redshift-alpha/test/integ.cluster-resource-action.js.snapshot/ResourceActionIntegDefaultTestDeployAssert086BABC4.template.json

+36
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: packages/@aws-cdk/aws-redshift-alpha/test/integ.cluster-resource-action.js.snapshot/ResourceActionStack.assets.json

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)