diff --git a/packages/@aws-cdk/aws-redshift/README.md b/packages/@aws-cdk/aws-redshift/README.md index 9c7897fb28e39..66af962185f72 100644 --- a/packages/@aws-cdk/aws-redshift/README.md +++ b/packages/@aws-cdk/aws-redshift/README.md @@ -300,6 +300,37 @@ cluster.addRotationMultiUser('MultiUserRotation', { }); ``` +## Adding Parameters + +You can add a parameter to a parameter group with`ClusterParameterGroup.addParameter()`. + +```ts +const params = new ClusterParameterGroup(stack, 'Params', { + description: 'desc', + parameters: { + require_ssl: 'true', + }, +}); + +params.addParameter('enable_user_activity_logging', 'true'); +``` + +Additionally, you can add a parameter to the cluster's associated parameter group with `Cluster.addToParameterGroup()`. If the cluster does not have an associated parameter group, a new parameter group is created. + +```ts +declare const vpc: ec2.Vpc; + +const cluster = new Cluster(this, 'Cluster', { + masterUser: { + masterUsername: 'admin', + masterPassword: cdk.SecretValue.unsafePlainText('tooshort'), + }, + vpc, +}); + +cluster.addToParameterGroup('enable_user_activity_logging', 'true'); +``` + ## Elastic IP 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 --git a/packages/@aws-cdk/aws-redshift/lib/cluster.ts b/packages/@aws-cdk/aws-redshift/lib/cluster.ts index f1d1a05c4903a..f888bc8cf309c 100644 --- a/packages/@aws-cdk/aws-redshift/lib/cluster.ts +++ b/packages/@aws-cdk/aws-redshift/lib/cluster.ts @@ -7,7 +7,7 @@ import { Duration, IResource, RemovalPolicy, Resource, SecretValue, Token } from import { Construct } from 'constructs'; import { DatabaseSecret } from './database-secret'; import { Endpoint } from './endpoint'; -import { IClusterParameterGroup } from './parameter-group'; +import { ClusterParameterGroup, IClusterParameterGroup } from './parameter-group'; import { CfnCluster } from './redshift.generated'; import { ClusterSubnetGroup, IClusterSubnetGroup } from './subnet-group'; @@ -360,6 +360,7 @@ export interface ClusterProps { * A new or imported clustered database. */ abstract class ClusterBase extends Resource implements ICluster { + /** * Name of the cluster */ @@ -405,7 +406,6 @@ export class Cluster extends ClusterBase { public readonly instanceIdentifiers: string[] = []; public readonly clusterEndpoint = new Endpoint(attrs.clusterEndpointAddress, attrs.clusterEndpointPort); } - return new Import(scope, id); } @@ -442,6 +442,16 @@ export class Cluster extends ClusterBase { */ private readonly vpcSubnets?: ec2.SubnetSelection; + /** + * The underlying CfnCluster + */ + private readonly cluster: CfnCluster; + + /** + * The cluster's parameter group + */ + protected parameterGroup?: IClusterParameterGroup; + constructor(scope: Construct, id: string, props: ClusterProps) { super(scope, id); @@ -449,6 +459,7 @@ export class Cluster extends ClusterBase { this.vpcSubnets = props.vpcSubnets ?? { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, }; + this.parameterGroup = props.parameterGroup; const removalPolicy = props.removalPolicy ?? RemovalPolicy.RETAIN; @@ -509,7 +520,7 @@ export class Cluster extends ClusterBase { ); } - const cluster = new CfnCluster(this, 'Resource', { + this.cluster = new CfnCluster(this, 'Resource', { // Basic allowVersionUpgrade: true, automatedSnapshotRetentionPeriod: 1, @@ -538,15 +549,15 @@ export class Cluster extends ClusterBase { elasticIp: props.elasticIp, }); - cluster.applyRemovalPolicy(removalPolicy, { + this.cluster.applyRemovalPolicy(removalPolicy, { applyToUpdateReplacePolicy: true, }); - this.clusterName = cluster.ref; + this.clusterName = this.cluster.ref; // create a number token that represents the port of the cluster - const portAttribute = Token.asNumber(cluster.attrEndpointPort); - this.clusterEndpoint = new Endpoint(cluster.attrEndpointAddress, portAttribute); + const portAttribute = Token.asNumber(this.cluster.attrEndpointPort); + this.clusterEndpoint = new Endpoint(this.cluster.attrEndpointAddress, portAttribute); if (secret) { this.secret = secret.attach(this); @@ -619,4 +630,26 @@ export class Cluster extends ClusterBase { return nodeCount; } } + + /** + * Adds a parameter to the Clusters' parameter group + * + * @param name the parameter name + * @param value the parameter name + */ + public addToParameterGroup(name: string, value: string): void { + if (!this.parameterGroup) { + const param: { [name: string]: string } = {}; + param[name] = value; + this.parameterGroup = new ClusterParameterGroup(this, 'ParameterGroup', { + description: this.cluster.clusterIdentifier ? `Parameter Group for the ${this.cluster.clusterIdentifier} Redshift cluster` : 'Cluster parameter group for family redshift-1.0', + parameters: param, + }); + this.cluster.clusterParameterGroupName = this.parameterGroup.clusterParameterGroupName; + } else if (this.parameterGroup instanceof ClusterParameterGroup) { + this.parameterGroup.addParameter(name, value); + } else { + throw new Error('Cannot add a parameter to an imported parameter group.'); + } + } } diff --git a/packages/@aws-cdk/aws-redshift/lib/parameter-group.ts b/packages/@aws-cdk/aws-redshift/lib/parameter-group.ts index 7fb570bc23ce6..831b79d42dc46 100644 --- a/packages/@aws-cdk/aws-redshift/lib/parameter-group.ts +++ b/packages/@aws-cdk/aws-redshift/lib/parameter-group.ts @@ -18,6 +18,7 @@ export interface IClusterParameterGroup extends IResource { * A new cluster or instance parameter group */ abstract class ClusterParameterGroupBase extends Resource implements IClusterParameterGroup { + /** * The name of the parameter group */ @@ -62,17 +63,46 @@ export class ClusterParameterGroup extends ClusterParameterGroupBase { */ public readonly clusterParameterGroupName: string; + /** + * The parameters in the parameter group + */ + readonly parameters: { [name: string]: string }; + + /** + * The underlying CfnClusterParameterGroup + */ + private readonly resource: CfnClusterParameterGroup; + constructor(scope: Construct, id: string, props: ClusterParameterGroupProps) { super(scope, id); - - const resource = new CfnClusterParameterGroup(this, 'Resource', { + this.parameters = props.parameters; + this.resource = new CfnClusterParameterGroup(this, 'Resource', { description: props.description || 'Cluster parameter group for family redshift-1.0', parameterGroupFamily: 'redshift-1.0', - parameters: Object.entries(props.parameters).map(([name, value]) => { - return { parameterName: name, parameterValue: value }; - }), + parameters: this.parseParameters(), }); - this.clusterParameterGroupName = resource.ref; + this.clusterParameterGroupName = this.resource.ref; + } + private parseParameters(): any { + return Object.entries(this.parameters).map(([name, value]) => { + return { parameterName: name, parameterValue: value }; + }); + } + + /** + * Adds a parameter to the parameter group + * + * @param name the parameter name + * @param value the parameter name + */ + public addParameter(name: string, value: string): void { + const existingValue = Object.entries(this.parameters).find(([key, _]) => key === name)?.[1]; + if (existingValue === undefined) { + this.parameters[name] = value; + this.resource.parameters = this.parseParameters(); + } else if (existingValue !== value) { + throw new Error(`The parameter group already contains the parameter "${name}", but with a different value (Given: ${value}, Existing: ${existingValue}).`); + } } } diff --git a/packages/@aws-cdk/aws-redshift/test/cluster.test.ts b/packages/@aws-cdk/aws-redshift/test/cluster.test.ts index 703abd29e1e84..49f52e91dadb3 100644 --- a/packages/@aws-cdk/aws-redshift/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-redshift/test/cluster.test.ts @@ -253,27 +253,116 @@ test('create an encrypted cluster with custom KMS key', () => { }, }); }); +describe('parameter group', () => { + test('cluster instantiated with parameter group', () => { + // WHEN + const group = new ClusterParameterGroup(stack, 'Params', { + description: 'bye', + parameters: { + param: 'value', + }, + }); + + new Cluster(stack, 'Redshift', { + masterUser: { + masterUsername: 'admin', + }, + vpc, + parameterGroup: group, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { + ClusterParameterGroupName: { Ref: 'ParamsA8366201' }, + }); -test('cluster with parameter group', () => { - // WHEN - const group = new ClusterParameterGroup(stack, 'Params', { - description: 'bye', - parameters: { - param: 'value', - }, }); - new Cluster(stack, 'Redshift', { - masterUser: { - masterUsername: 'admin', - }, - vpc, - parameterGroup: group, + test('Adding to the cluster parameter group on a cluster not instantiated with a parameter group', () => { + + // WHEN + const cluster = new Cluster(stack, 'Redshift', { + clusterName: 'foobar', + masterUser: { + masterUsername: 'admin', + }, + vpc, + }); + + cluster.addToParameterGroup('foo', 'bar'); + + const template = Template.fromStack(stack); + template.hasResourceProperties('AWS::Redshift::Cluster', { + ClusterParameterGroupName: { Ref: Match.anyValue() }, + }); + + template.hasResourceProperties('AWS::Redshift::ClusterParameterGroup', { + Description: 'Parameter Group for the foobar Redshift cluster', + ParameterGroupFamily: 'redshift-1.0', + Parameters: [ + { + ParameterName: 'foo', + ParameterValue: 'bar', + }, + ], + }); }); - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { - ClusterParameterGroupName: { Ref: 'ParamsA8366201' }, + test('Adding to the cluster parameter group on a cluster instantiated with a parameter group', () => { + + // WHEN + const group = new ClusterParameterGroup(stack, 'Params', { + description: 'lorem ipsum', + parameters: { + param: 'value', + }, + }); + + const cluster = new Cluster(stack, 'Redshift', { + masterUser: { + masterUsername: 'admin', + }, + vpc, + parameterGroup: group, + }); + cluster.addToParameterGroup('foo', 'bar'); + + const template = Template.fromStack(stack); + template.hasResourceProperties('AWS::Redshift::Cluster', { + ClusterParameterGroupName: { Ref: Match.anyValue() }, + }); + + template.hasResourceProperties('AWS::Redshift::ClusterParameterGroup', { + Description: 'lorem ipsum', + ParameterGroupFamily: 'redshift-1.0', + Parameters: [ + { + ParameterName: 'param', + ParameterValue: 'value', + }, + { + ParameterName: 'foo', + ParameterValue: 'bar', + }, + ], + }); + }); + + test('Adding a parameter to an IClusterParameterGroup', () => { + // GIVEN + const cluster = new Cluster(stack, 'Redshift', { + clusterName: 'foobar', + parameterGroup: ClusterParameterGroup.fromClusterParameterGroupName(stack, 'Params', 'foo'), + masterUser: { + masterUsername: 'admin', + }, + vpc, + }); + + // WHEN + expect(() => cluster.addToParameterGroup('param', 'value2')) + // THEN + .toThrowError('Cannot add a parameter to an imported parameter group'); }); }); @@ -374,7 +463,7 @@ test('throws validation error when trying to set encryptionKey without enabling // THEN expect(() => { - new Cluster(stack, 'Redshift', props ); + new Cluster(stack, 'Redshift', props); }).toThrowError(); }); diff --git a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/aws-cdk-redshift-cluster-database.assets.json b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/aws-cdk-redshift-cluster-database.assets.json index 8345a0b1525bc..f92a39bfbbcef 100644 --- a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/aws-cdk-redshift-cluster-database.assets.json +++ b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/aws-cdk-redshift-cluster-database.assets.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "21.0.0", "files": { "fb53353ae3322d38cf92fc2d8a73910a88c06a725900f0815aeaab985e6a19e3": { "source": { @@ -27,7 +27,7 @@ } } }, - "824f9ae87e8bb069d7316bd7955079be850bbe42b32fc16c6c57738078b57296": { + "784177efbde5b0ae9662ffc9f5f85895be269347870d0564efaa1281f8a1c38e": { "source": { "path": "aws-cdk-redshift-cluster-database.template.json", "packaging": "file" @@ -35,7 +35,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "824f9ae87e8bb069d7316bd7955079be850bbe42b32fc16c6c57738078b57296.json", + "objectKey": "784177efbde5b0ae9662ffc9f5f85895be269347870d0564efaa1281f8a1c38e.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/aws-cdk-redshift-cluster-database.template.json b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/aws-cdk-redshift-cluster-database.template.json index b4677ceaf31b1..2d14182a7f2ad 100644 --- a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/aws-cdk-redshift-cluster-database.template.json +++ b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/aws-cdk-redshift-cluster-database.template.json @@ -565,6 +565,9 @@ "NodeType": "dc2.large", "AllowVersionUpgrade": true, "AutomatedSnapshotRetentionPeriod": 1, + "ClusterParameterGroupName": { + "Ref": "ClusterParameterGroup879806FD" + }, "ClusterSubnetGroupName": { "Ref": "ClusterSubnetsDCFA5CB7" }, @@ -586,6 +589,21 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "ClusterParameterGroup879806FD": { + "Type": "AWS::Redshift::ClusterParameterGroup", + "Properties": { + "Description": "Cluster parameter group for family redshift-1.0", + "ParameterGroupFamily": "redshift-1.0", + "Parameters": [ + { + "ParameterName": "enable_user_activity_logging", + "ParameterValue": "true" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, "UserSecretE2C04A69": { "Type": "AWS::SecretsManager::Secret", "Properties": { diff --git a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/cdk.out b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/cdk.out index 588d7b269d34f..8ecc185e9dbee 100644 --- a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/integ.json b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/integ.json index a0f6a09b6ba58..0920057138199 100644 --- a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/integ.json +++ b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "21.0.0", "testCases": { "integ.database": { "stacks": [ diff --git a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/manifest.json index 65efefc2bab16..fe9068d22e8a7 100644 --- a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "21.0.0", "artifacts": { "Tree": { "type": "cdk:tree", @@ -23,7 +23,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/824f9ae87e8bb069d7316bd7955079be850bbe42b32fc16c6c57738078b57296.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/784177efbde5b0ae9662ffc9f5f85895be269347870d0564efaa1281f8a1c38e.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -213,6 +213,15 @@ "data": "ClusterEB0386A7" } ], + "/aws-cdk-redshift-cluster-database/Cluster/ParameterGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ClusterParameterGroup879806FD", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] + } + ], "/aws-cdk-redshift-cluster-database/User/Secret/Resource": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/tree.json b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/tree.json index c10837094826a..1f4c6c4140f6b 100644 --- a/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/tree.json +++ b/packages/@aws-cdk/aws-redshift/test/database.integ.snapshot/tree.json @@ -9,7 +9,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.92" } }, "aws-cdk-redshift-cluster-database": { @@ -91,8 +91,8 @@ "id": "Acl", "path": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -258,8 +258,8 @@ "id": "Acl", "path": "aws-cdk-redshift-cluster-database/Vpc/PublicSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -425,8 +425,8 @@ "id": "Acl", "path": "aws-cdk-redshift-cluster-database/Vpc/PrivateSubnet1/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -544,8 +544,8 @@ "id": "Acl", "path": "aws-cdk-redshift-cluster-database/Vpc/PrivateSubnet2/Acl", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } }, "RouteTable": { @@ -874,6 +874,9 @@ "nodeType": "dc2.large", "allowVersionUpgrade": true, "automatedSnapshotRetentionPeriod": 1, + "clusterParameterGroupName": { + "Ref": "ClusterParameterGroup879806FD" + }, "clusterSubnetGroupName": { "Ref": "ClusterSubnetsDCFA5CB7" }, @@ -897,6 +900,37 @@ "fqn": "@aws-cdk/aws-redshift.CfnCluster", "version": "0.0.0" } + }, + "ParameterGroup": { + "id": "ParameterGroup", + "path": "aws-cdk-redshift-cluster-database/Cluster/ParameterGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-redshift-cluster-database/Cluster/ParameterGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Redshift::ClusterParameterGroup", + "aws:cdk:cloudformation:props": { + "description": "Cluster parameter group for family redshift-1.0", + "parameterGroupFamily": "redshift-1.0", + "parameters": [ + { + "parameterName": "enable_user_activity_logging", + "parameterValue": "true" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-redshift.CfnClusterParameterGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-redshift.ClusterParameterGroup", + "version": "0.0.0" + } } }, "constructInfo": { @@ -1104,8 +1138,8 @@ "id": "Stage", "path": "aws-cdk-redshift-cluster-database/User/Resource/Provider/framework-onEvent/Code/Stage", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" } }, "AssetBucket": { @@ -1181,20 +1215,20 @@ "id": "Default", "path": "aws-cdk-redshift-cluster-database/User/Resource/Resource/Default", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.92" } }, "TablePrivileges": { @@ -1338,8 +1372,8 @@ "id": "Stage", "path": "aws-cdk-redshift-cluster-database/User/TablePrivileges/Resource/Provider/framework-onEvent/Code/Stage", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" } }, "AssetBucket": { @@ -1415,26 +1449,26 @@ "id": "Default", "path": "aws-cdk-redshift-cluster-database/User/TablePrivileges/Resource/Resource/Default", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.92" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.92" } } }, @@ -1561,8 +1595,8 @@ "id": "Stage", "path": "aws-cdk-redshift-cluster-database/Query Redshift Database3de5bea727da479686625efb56431b5f/Code/Stage", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" } }, "AssetBucket": { @@ -1754,8 +1788,8 @@ "id": "Stage", "path": "aws-cdk-redshift-cluster-database/Table/Resource/Provider/framework-onEvent/Code/Stage", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" } }, "AssetBucket": { @@ -1831,20 +1865,20 @@ "id": "Default", "path": "aws-cdk-redshift-cluster-database/Table/Resource/Resource/Default", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.CfnResource", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.CustomResource", + "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.92" } } }, @@ -1855,14 +1889,14 @@ } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/integ.database.ts b/packages/@aws-cdk/aws-redshift/test/integ.database.ts index c2a362310cf5c..45a67f26f499e 100644 --- a/packages/@aws-cdk/aws-redshift/test/integ.database.ts +++ b/packages/@aws-cdk/aws-redshift/test/integ.database.ts @@ -31,6 +31,8 @@ const cluster = new redshift.Cluster(stack, 'Cluster', { encryptionKey: new kms.Key(stack, 'custom-kms-key'), }); +cluster.addToParameterGroup('enable_user_activity_logging', 'true'); + const databaseOptions = { cluster: cluster, databaseName: databaseName, @@ -47,5 +49,4 @@ const table = new redshift.Table(stack, 'Table', { sortStyle: redshift.TableSortStyle.INTERLEAVED, }); table.grant(user, redshift.TableAction.INSERT, redshift.TableAction.DELETE); - app.synth(); diff --git a/packages/@aws-cdk/aws-redshift/test/parameter-group.test.ts b/packages/@aws-cdk/aws-redshift/test/parameter-group.test.ts index 1853fc0f5baf5..115c19cc603a8 100644 --- a/packages/@aws-cdk/aws-redshift/test/parameter-group.test.ts +++ b/packages/@aws-cdk/aws-redshift/test/parameter-group.test.ts @@ -26,4 +26,78 @@ test('create a cluster parameter group', () => { ], }); +}); + +describe('Adding parameters to an existing group', () => { + test('Adding a new parameter', () => { + // GIVEN + const stack = new cdk.Stack(); + const params = new ClusterParameterGroup(stack, 'Params', { + description: 'desc', + parameters: { + param: 'value', + }, + }); + + // WHEN + params.addParameter('param2', 'value2'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::ClusterParameterGroup', { + Description: 'desc', + ParameterGroupFamily: 'redshift-1.0', + Parameters: [ + { + ParameterName: 'param', + ParameterValue: 'value', + }, + { + ParameterName: 'param2', + ParameterValue: 'value2', + }, + ], + }); + }); + + test('Adding an existing named parameter with the same value', () => { + // GIVEN + const stack = new cdk.Stack(); + const params = new ClusterParameterGroup(stack, 'Params', { + description: 'desc', + parameters: { + param: 'value', + }, + }); + + // WHEN + params.addParameter('param', 'value'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::ClusterParameterGroup', { + Description: 'desc', + ParameterGroupFamily: 'redshift-1.0', + Parameters: [ + { + ParameterName: 'param', + ParameterValue: 'value', + }, + ], + }); + }); + + test('Adding an existing named parameter with a different value', () => { + // GIVEN + const stack = new cdk.Stack(); + const params = new ClusterParameterGroup(stack, 'Params', { + description: 'desc', + parameters: { + param: 'value', + }, + }); + + // WHEN + expect(() => params.addParameter('param', 'value2')) + // THEN + .toThrowError('The parameter group already contains the parameter'); + }); }); \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot-assets-diff.integ.snapshot/manifest.json b/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot-assets-diff.integ.snapshot/manifest.json index d5518ce4bd0e1..0d7e598bc5bd2 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot-assets-diff.integ.snapshot/manifest.json +++ b/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot-assets-diff.integ.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "21.0.0", "artifacts": { "Tree": { "type": "cdk:tree", diff --git a/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot-assets.integ.snapshot/manifest.json b/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot-assets.integ.snapshot/manifest.json index 7c2c6d4d8cdce..606c37571a711 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot-assets.integ.snapshot/manifest.json +++ b/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot-assets.integ.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "21.0.0", "artifacts": { "Tree": { "type": "cdk:tree", diff --git a/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot.integ.snapshot/manifest.json b/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot.integ.snapshot/manifest.json index 7b8ed0311e8f0..5c9fd61ecec9f 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot.integ.snapshot/manifest.json +++ b/packages/@aws-cdk/integ-runner/test/test-data/test-with-snapshot.integ.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "21.0.0", "artifacts": { "Tree": { "type": "cdk:tree",