Skip to content

Commit 3ba9088

Browse files
authored
feat(rds): simpler way to configure parameters for instance and cluster (#18126)
Fixes #18124 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 9858002 commit 3ba9088

File tree

6 files changed

+270
-4
lines changed

6 files changed

+270
-4
lines changed

packages/@aws-cdk/aws-rds/README.md

+45
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,51 @@ new rds.OptionGroup(this, 'Options', {
527527
});
528528
```
529529

530+
## Parameter Groups
531+
532+
Database parameters specify how the database is configured.
533+
For example, database parameters can specify the amount of resources, such as memory, to allocate to a database.
534+
You manage your database configuration by associating your DB instances with parameter groups.
535+
Amazon RDS defines parameter groups with default settings.
536+
537+
You can create your own parameter group for your cluster or instance and associate it with your database:
538+
539+
```ts
540+
declare const vpc: ec2.Vpc;
541+
542+
const parameterGroup = new rds.ParameterGroup(this, 'ParameterGroup', {
543+
engine: rds.DatabaseInstanceEngine.sqlServerEe({
544+
version: rds.SqlServerEngineVersion.VER_11,
545+
}),
546+
parameters: {
547+
locks: '100',
548+
},
549+
});
550+
551+
new rds.DatabaseInstance(this, 'Database', {
552+
engine: rds.DatabaseInstanceEngine.SQL_SERVER_EE,
553+
vpc,
554+
parameterGroup,
555+
});
556+
```
557+
558+
Another way to specify parameters is to use the inline field `parameters` that creates an RDS parameter group for you.
559+
You can use this if you do not want to reuse the parameter group instance for different instances:
560+
561+
```ts
562+
declare const vpc: ec2.Vpc;
563+
564+
new rds.DatabaseInstance(this, 'Database', {
565+
engine: rds.DatabaseInstanceEngine.sqlServerEe({ version: rds.SqlServerEngineVersion.VER_11 }),
566+
vpc,
567+
parameters: {
568+
locks: '100',
569+
},
570+
});
571+
```
572+
573+
You cannot specify a parameter map and a parameter group at the same time.
574+
530575
## Serverless
531576

532577
[Amazon Aurora Serverless](https://aws.amazon.com/rds/aurora/serverless/) is an on-demand, auto-scaling configuration for Amazon

packages/@aws-cdk/aws-rds/lib/cluster.ts

+39-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Construct } from 'constructs';
1010
import { IClusterEngine } from './cluster-engine';
1111
import { DatabaseClusterAttributes, IDatabaseCluster } from './cluster-ref';
1212
import { Endpoint } from './endpoint';
13-
import { IParameterGroup } from './parameter-group';
13+
import { IParameterGroup, ParameterGroup } from './parameter-group';
1414
import { DEFAULT_PASSWORD_EXCLUDE_CHARS, defaultDeletionProtection, renderCredentials, setupS3ImportExport, helperRemovalPolicy, renderUnless } from './private/util';
1515
import { BackupProps, Credentials, InstanceProps, PerformanceInsightRetention, RotationSingleUserOptions, RotationMultiUserOptions } from './props';
1616
import { DatabaseProxy, DatabaseProxyOptions, ProxyTarget } from './proxy';
@@ -116,6 +116,16 @@ interface DatabaseClusterBaseProps {
116116
*/
117117
readonly parameterGroup?: IParameterGroup;
118118

119+
/**
120+
* The parameters in the DBClusterParameterGroup to create automatically
121+
*
122+
* You can only specify parameterGroup or parameters but not both.
123+
* You need to use a versioned engine to auto-generate a DBClusterParameterGroup.
124+
*
125+
* @default - None
126+
*/
127+
readonly parameters?: { [key: string]: string };
128+
119129
/**
120130
* The removal policy to apply when the cluster and its instances are removed
121131
* from the stack or replaced during an update.
@@ -338,11 +348,23 @@ abstract class DatabaseClusterNew extends DatabaseClusterBase {
338348
];
339349

340350
let { s3ImportRole, s3ExportRole } = setupS3ImportExport(this, props, /* combineRoles */ false);
351+
352+
if (props.parameterGroup && props.parameters) {
353+
throw new Error('You cannot specify both parameterGroup and parameters');
354+
}
355+
const parameterGroup = props.parameterGroup ?? (
356+
props.parameters
357+
? new ParameterGroup(this, 'ParameterGroup', {
358+
engine: props.engine,
359+
parameters: props.parameters,
360+
})
361+
: undefined
362+
);
341363
// bind the engine to the Cluster
342364
const clusterEngineBindConfig = props.engine.bindToCluster(this, {
343365
s3ImportRole,
344366
s3ExportRole,
345-
parameterGroup: props.parameterGroup,
367+
parameterGroup,
346368
});
347369

348370
const clusterAssociatedRoles: CfnDBCluster.DBClusterRoleProperty[] = [];
@@ -722,7 +744,21 @@ function createInstances(cluster: DatabaseClusterNew, props: DatabaseClusterBase
722744
}
723745

724746
const instanceType = instanceProps.instanceType ?? ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MEDIUM);
725-
const instanceParameterGroupConfig = instanceProps.parameterGroup?.bindToInstance({});
747+
748+
if (instanceProps.parameterGroup && instanceProps.parameters) {
749+
throw new Error('You cannot specify both parameterGroup and parameters');
750+
}
751+
752+
const instanceParameterGroup = instanceProps.parameterGroup ?? (
753+
instanceProps.parameters
754+
? new ParameterGroup(cluster, 'InstanceParameterGroup', {
755+
engine: props.engine,
756+
parameters: instanceProps.parameters,
757+
})
758+
: undefined
759+
);
760+
const instanceParameterGroupConfig = instanceParameterGroup?.bindToInstance({});
761+
726762
for (let i = 0; i < instanceCount; i++) {
727763
const instanceIndex = i + 1;
728764
const instanceIdentifier = props.instanceIdentifierBase != null ? `${props.instanceIdentifierBase}${instanceIndex}` :

packages/@aws-cdk/aws-rds/lib/instance.ts

+23-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { DatabaseSecret } from './database-secret';
1212
import { Endpoint } from './endpoint';
1313
import { IInstanceEngine } from './instance-engine';
1414
import { IOptionGroup } from './option-group';
15-
import { IParameterGroup } from './parameter-group';
15+
import { IParameterGroup, ParameterGroup } from './parameter-group';
1616
import { DEFAULT_PASSWORD_EXCLUDE_CHARS, defaultDeletionProtection, engineDescription, renderCredentials, setupS3ImportExport, helperRemovalPolicy, renderUnless } from './private/util';
1717
import { Credentials, PerformanceInsightRetention, RotationMultiUserOptions, RotationSingleUserOptions, SnapshotCredentials } from './props';
1818
import { DatabaseProxy, DatabaseProxyOptions, ProxyTarget } from './proxy';
@@ -822,6 +822,16 @@ export interface DatabaseInstanceSourceProps extends DatabaseInstanceNewProps {
822822
* @default - no name
823823
*/
824824
readonly databaseName?: string;
825+
826+
/**
827+
* The parameters in the DBParameterGroup to create automatically
828+
*
829+
* You can only specify parameterGroup or parameters but not both.
830+
* You need to use a versioned engine to auto-generate a DBParameterGroup.
831+
*
832+
* @default - None
833+
*/
834+
readonly parameters?: { [key: string]: string };
825835
}
826836

827837
/**
@@ -877,6 +887,17 @@ abstract class DatabaseInstanceSource extends DatabaseInstanceNew implements IDa
877887

878888
this.instanceType = props.instanceType ?? ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE);
879889

890+
if (props.parameterGroup && props.parameters) {
891+
throw new Error('You cannot specify both parameterGroup and parameters');
892+
}
893+
894+
const dbParameterGroupName = props.parameters
895+
? new ParameterGroup(this, 'ParameterGroup', {
896+
engine: props.engine,
897+
parameters: props.parameters,
898+
}).bindToInstance({}).parameterGroupName
899+
: this.newCfnProps.dbParameterGroupName;
900+
880901
this.sourceCfnProps = {
881902
...this.newCfnProps,
882903
associatedRoles: instanceAssociatedRoles.length > 0 ? instanceAssociatedRoles : undefined,
@@ -888,6 +909,7 @@ abstract class DatabaseInstanceSource extends DatabaseInstanceNew implements IDa
888909
engineVersion: props.engine.engineVersion?.fullVersion,
889910
licenseModel: props.licenseModel,
890911
timezone: props.timezone,
912+
dbParameterGroupName,
891913
};
892914
}
893915

packages/@aws-cdk/aws-rds/lib/props.ts

+10
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ export interface InstanceProps {
4343
*/
4444
readonly parameterGroup?: IParameterGroup;
4545

46+
/**
47+
* The parameters in the DBParameterGroup to create automatically
48+
*
49+
* You can only specify parameterGroup or parameters but not both.
50+
* You need to use a versioned engine to auto-generate a DBParameterGroup.
51+
*
52+
* @default - None
53+
*/
54+
readonly parameters?: { [key: string]: string };
55+
4656
/**
4757
* Whether to enable Performance Insights for the DB instance.
4858
*

packages/@aws-cdk/aws-rds/test/cluster.test.ts

+107
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import * as cxapi from '@aws-cdk/cx-api';
1010
import {
1111
AuroraEngineVersion, AuroraMysqlEngineVersion, AuroraPostgresEngineVersion, CfnDBCluster, Credentials, DatabaseCluster,
1212
DatabaseClusterEngine, DatabaseClusterFromSnapshot, ParameterGroup, PerformanceInsightRetention, SubnetGroup, DatabaseSecret,
13+
DatabaseInstanceEngine, SqlServerEngineVersion,
1314
} from '../lib';
1415

1516
describe('cluster', () => {
@@ -322,6 +323,112 @@ describe('cluster', () => {
322323
});
323324
});
324325

326+
test('cluster with inline parameter group', () => {
327+
// GIVEN
328+
const stack = testStack();
329+
const vpc = new ec2.Vpc(stack, 'VPC');
330+
331+
// WHEN
332+
new DatabaseCluster(stack, 'Database', {
333+
engine: DatabaseClusterEngine.AURORA,
334+
parameters: {
335+
locks: '100',
336+
},
337+
instanceProps: {
338+
vpc,
339+
parameters: {
340+
locks: '200',
341+
},
342+
},
343+
});
344+
345+
Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', {
346+
DBClusterParameterGroupName: {
347+
Ref: 'DatabaseParameterGroup2A921026',
348+
},
349+
});
350+
351+
Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBClusterParameterGroup', {
352+
Family: 'aurora5.6',
353+
Parameters: {
354+
locks: '100',
355+
},
356+
});
357+
358+
Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', {
359+
DBParameterGroupName: {
360+
Ref: 'DatabaseInstanceParameterGroup6968C5BF',
361+
},
362+
});
363+
364+
Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBParameterGroup', {
365+
Family: 'aurora5.6',
366+
Parameters: {
367+
locks: '200',
368+
},
369+
});
370+
});
371+
372+
test('cluster with inline parameter group and parameterGroup arg fails', () => {
373+
// GIVEN
374+
const stack = testStack();
375+
const vpc = new ec2.Vpc(stack, 'VPC');
376+
const parameterGroup = new ParameterGroup(stack, 'ParameterGroup', {
377+
engine: DatabaseInstanceEngine.sqlServerEe({
378+
version: SqlServerEngineVersion.VER_11,
379+
}),
380+
parameters: {
381+
locks: '50',
382+
},
383+
});
384+
385+
expect(() => {
386+
new DatabaseCluster(stack, 'Database', {
387+
engine: DatabaseClusterEngine.AURORA,
388+
parameters: {
389+
locks: '100',
390+
},
391+
parameterGroup,
392+
instanceProps: {
393+
vpc,
394+
parameters: {
395+
locks: '200',
396+
},
397+
},
398+
});
399+
}).toThrow(/You cannot specify both parameterGroup and parameters/);
400+
});
401+
402+
test('instance with inline parameter group and parameterGroup arg fails', () => {
403+
// GIVEN
404+
const stack = testStack();
405+
const vpc = new ec2.Vpc(stack, 'VPC');
406+
const parameterGroup = new ParameterGroup(stack, 'ParameterGroup', {
407+
engine: DatabaseInstanceEngine.sqlServerEe({
408+
version: SqlServerEngineVersion.VER_11,
409+
}),
410+
parameters: {
411+
locks: '50',
412+
},
413+
});
414+
415+
expect(() => {
416+
new DatabaseCluster(stack, 'Database', {
417+
engine: DatabaseClusterEngine.AURORA,
418+
parameters: {
419+
locks: '100',
420+
},
421+
instanceProps: {
422+
vpc,
423+
parameterGroup,
424+
parameters: {
425+
locks: '200',
426+
},
427+
},
428+
});
429+
}).toThrow(/You cannot specify both parameterGroup and parameters/);
430+
});
431+
325432
describe('performance insights', () => {
326433
test('cluster with all performance insights properties', () => {
327434
// GIVEN

packages/@aws-cdk/aws-rds/test/instance.test.ts

+46
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,52 @@ describe('instance', () => {
246246
});
247247
});
248248

249+
test('instance with inline parameter group', () => {
250+
// WHEN
251+
new rds.DatabaseInstance(stack, 'Database', {
252+
engine: rds.DatabaseInstanceEngine.sqlServerEe({ version: rds.SqlServerEngineVersion.VER_11 }),
253+
vpc,
254+
parameters: {
255+
locks: '100',
256+
},
257+
});
258+
259+
Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', {
260+
DBParameterGroupName: {
261+
Ref: 'DatabaseParameterGroup2A921026',
262+
},
263+
});
264+
265+
Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBParameterGroup', {
266+
Family: 'sqlserver-ee-11.0',
267+
Parameters: {
268+
locks: '100',
269+
},
270+
});
271+
});
272+
273+
test('instance with inline parameter group and parameterGroup arg fails', () => {
274+
const parameterGroup = new rds.ParameterGroup(stack, 'ParameterGroup', {
275+
engine: rds.DatabaseInstanceEngine.sqlServerEe({
276+
version: rds.SqlServerEngineVersion.VER_11,
277+
}),
278+
parameters: {
279+
key: 'value',
280+
},
281+
});
282+
283+
expect(() => {
284+
new rds.DatabaseInstance(stack, 'Database', {
285+
engine: rds.DatabaseInstanceEngine.sqlServerEe({ version: rds.SqlServerEngineVersion.VER_11 }),
286+
vpc,
287+
parameters: {
288+
locks: '100',
289+
},
290+
parameterGroup,
291+
});
292+
}).toThrow(/You cannot specify both parameterGroup and parameters/);
293+
});
294+
249295
test('can specify subnet type', () => {
250296
new rds.DatabaseInstance(stack, 'Instance', {
251297
engine: rds.DatabaseInstanceEngine.mysql({

0 commit comments

Comments
 (0)