Skip to content

Commit

Permalink
feat(rds): change the way Engines are modeled
Browse files Browse the repository at this point in the history
Change the types of the engine from DatabaseClusterEngine and its subclass,
DatabaseInstanceEngine, to 2 separate interfaces,
IClusterEngine and IInstanceEngine.
Add properties to each of them,
including engineVersion,
and thus stop taking engineVersion separately as a property for instances,
clusters and OptionGroups.
Allow changing the version of an existing engine to an arbitrary string.
Add a bind()-like protocol to both IClusterEngine and IInstanceEngine,
which allows expressing validation and default values logic directly in the engines,
instead of hard-coding them in cluster and instance.
Because of those changes, creating a default cluster with Aurora MySQL or Postgres engines now works out of the box,
instead of failing at deploy time.
We also correctly set the port for Postgres clusters to 5432,
instead of leaving it as the default 3306 (which is the MySQL port).

Fixes aws#2213
Fixes aws#2512
Fixes aws#4150
Fixes aws#5126
Fixes aws#7072

BREAKING CHANGE: the class DatabaseClusterEngine has been replaced with the interface IClusterEngine in the type of DatabaseClusterProps.engine
* **rds**: the class DatabaseInstanceEngine has been replaced with the interface IInstanceEngine in the type of DatabaseInstanceSourceProps.engine
* **rds**: DatabaseClusterProps.engineVersion has been removed; instead, create an IClusterEngine with a specific version using the static factory methods in DatabaseClusterEngine
* **rds**: DatabaseInstanceSourceProps.engineVersion has been removed; instead, create an IInstanceEngine with a specific version using the static factory methods in DatabaseInstanceEngine
* **rds**: the property majorEngineVersion can no longer be passed when creating an OptionGroup; instead, create an IInstanceEngine with a specific version using the static factory methods in DatabaseInstanceEngine
  • Loading branch information
skinny85 committed Jun 22, 2020
1 parent b27d5a3 commit d58f8ef
Show file tree
Hide file tree
Showing 16 changed files with 1,196 additions and 424 deletions.
122 changes: 84 additions & 38 deletions packages/@aws-cdk/aws-rds/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## Amazon Relational Database Service Construct Library

<!--BEGIN STABILITY BANNER-->
---

Expand All @@ -13,86 +14,125 @@
---
<!--END STABILITY BANNER-->

### Starting a Clustered Database
```typescript
import * as rds from '@aws-cdk/aws-rds';
```

### Starting a clustered database

To set up a clustered database (like Aurora), define a `DatabaseCluster`. You must
always launch a database in a VPC. Use the `vpcSubnets` attribute to control whether
your instances will be launched privately or publicly:

```ts
const cluster = new DatabaseCluster(this, 'Database', {
engine: DatabaseClusterEngine.AURORA,
masterUser: {
username: 'clusteradmin'
const cluster = new rds.DatabaseCluster(this, 'Database', {
engine: rds.DatabaseClusterEngine.AURORA,
masterUser: {
username: 'clusteradmin'
},
instanceProps: {
// optional, defaults to the engine's default instance type
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE,
},
instanceProps: {
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE,
},
vpc
}
vpc,
},
});
```

To use a specific version of the engine
(which is recommended, in order to avoid surprise updates when RDS add support for a newer version of the engine),
use the static factory methods on `DatabaseClusterEngine`:

```typescript
new rds.DatabaseCluster(this, 'Database', {
engine: rds.DatabaseClusterEngine.defaultAurora({
engineVersion: '5.6.mysql_aurora.1.17.9',
},
...
})
```
See [the AWS documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-database-instance.html#cfn-rds-dbinstance-engineversion)
for a list of the supported versions for each engine type.
By default, the master password will be generated and stored in AWS Secrets Manager with auto-generated description.
Your cluster will be empty by default. To add a default database upon construction, specify the
`defaultDatabaseName` attribute.
### Starting an Instance Database
### Starting an instance database
To set up a instance database, define a `DatabaseInstance`. You must
always launch a database in a VPC. Use the `vpcSubnets` attribute to control whether
your instances will be launched privately or publicly:
```ts
const instance = new DatabaseInstance(stack, 'Instance', {
engine: rds.DatabaseInstanceEngine.ORACLE_SE1,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
masterUsername: 'syscdk',
vpc
const instance = new rds.DatabaseInstance(this, 'Instance', {
engine: rds.DatabaseInstanceEngine.ORACLE_SE1,
// optional, defaults to the engine's default instance type
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
masterUsername: 'syscdk',
vpc,
});
```
By default, the master password will be generated and stored in AWS Secrets Manager.
You specify the engine version
(which is recommended, in order to avoid surprise updates when RDS add support for a newer version of the engine)
the same as with cluster,
by calling instance methods on the `engine`:
```typescript
const instance = new rds.DatabaseInstance(this, 'Instance', {
engine: rds.DatabaseInstanceEngine.ORACLE_SE1.withVersion('19.0.0.0'),
...
});
```
To use the storage auto scaling option of RDS you can specify the maximum allocated storage.
This is the upper limit to which RDS can automatically scale the storage. More info can be found
[here](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PIOPS.StorageTypes.html#USER_PIOPS.Autoscaling)
Example for max storage configuration:
```ts
const instance = new DatabaseInstance(stack, 'Instance', {
engine: rds.DatabaseInstanceEngine.ORACLE_SE1,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
masterUsername: 'syscdk',
vpc,
maxAllocatedStorage: 200
const instance = new rds.DatabaseInstance(this, 'Instance', {
engine: rds.DatabaseInstanceEngine.ORACLE_SE1,
// optional, defaults to the engine's default instance type
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
masterUsername: 'syscdk',
vpc,
maxAllocatedStorage: 200,
});
```
Use `DatabaseInstanceFromSnapshot` and `DatabaseInstanceReadReplica` to create an instance from snapshot or
a source database respectively:
```ts
new DatabaseInstanceFromSnapshot(stack, 'Instance', {
snapshotIdentifier: 'my-snapshot',
engine: rds.DatabaseInstanceEngine.POSTGRES,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE),
vpc
new rds.DatabaseInstanceFromSnapshot(stack, 'Instance', {
snapshotIdentifier: 'my-snapshot',
engine: rds.DatabaseInstanceEngine.POSTGRES,
// optional, defaults to the engine's default instance type
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE),
vpc,
});

new DatabaseInstanceReadReplica(stack, 'ReadReplica', {
sourceDatabaseInstance: sourceInstance,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE),
vpc
new rds.DatabaseInstanceReadReplica(stack, 'ReadReplica', {
sourceDatabaseInstance: sourceInstance,
instanceType: rds.DatabaseInstanceEngine.POSTGRES.defaultInstanceType,
vpc,
});
```
Creating a "production" Oracle database instance with option and parameter groups:
[example of setting up a production oracle instance](test/integ.instance.lit.ts)

### Instance events
To define Amazon CloudWatch event rules for database instances, use the `onEvent`
method:
Expand Down Expand Up @@ -122,7 +162,9 @@ const address = instance.instanceEndpoint.socketAddress; // "HOSTNAME:PORT"
```
### Rotating credentials
When the master password is generated and stored in AWS Secrets Manager, it can be rotated automatically:
```ts
instance.addRotationSingleUser(); // Will rotate automatically after 30 days
```
Expand Down Expand Up @@ -154,7 +196,9 @@ The rotation will start as soon as this user exists.
See also [@aws-cdk/aws-secretsmanager](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-secretsmanager/README.md) for credentials rotation of existing clusters/instances.
### Metrics
Database instances expose metrics (`cloudwatch.Metric`):
```ts
// The number of database connections in use (average over 5 minutes)
const dbConnections = instance.metricDatabaseConnections();
Expand All @@ -181,11 +225,13 @@ data into S3](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/postg
The following snippet sets up a database cluster with different S3 buckets where the data is imported and exported -
```ts
import * as s3 from '@aws-cdk/aws-s3';

const importBucket = new s3.Bucket(this, 'importbucket');
const exportBucket = new s3.Bucket(this, 'exportbucket');
new DatabaseCluster(this, 'dbcluster', {
// ...
s3ImportBuckets: [ importBucket ],
s3ExportBuckets: [ exportBucket ]
new rds.DatabaseCluster(this, 'dbcluster', {
// ...
s3ImportBuckets: [importBucket],
s3ExportBuckets: [exportBucket],
});
```
Loading

0 comments on commit d58f8ef

Please sign in to comment.