-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(rds): add support for database instances #2187
Changes from 12 commits
ef9a9cf
1c17af4
e55b6fc
8c31724
cc49f71
d798e0c
6cc4e88
c890989
2e5b611
ee391c8
fe17f60
2aed438
9249aff
3b9bc6e
4150e19
8078dcf
b91e3a3
737bcaa
b817d92
6dd669d
a9b8792
34627f8
305db7b
ab5c6f3
96f14ee
7c5526a
e7b62b0
4578cca
b589ed4
ee8d067
c2a2c92
e06616f
c8b185e
25e406f
f8ac7cb
13fb8c7
e852acf
c392fbb
28b0d59
6f8eec8
d044e64
c904e99
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,33 +45,85 @@ By default, the master password will be generated and stored in AWS Secrets Mana | |
Your cluster will be empty by default. To add a default database upon construction, specify the | ||
`defaultDatabaseName` attribute. | ||
|
||
### Starting an Instance Database | ||
To set up a instance database, create an instance of `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.OracleSE1, | ||
instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.Burstable2, ec2.InstanceSize.Small), | ||
masterUsername: 'syscdk', | ||
vpc | ||
}); | ||
``` | ||
By default, the master password will be generated and stored in AWS Secrets Manager. | ||
|
||
Use `DatabaseInstanceFromSnapshot` and `DatabaseInstanceReadReplica` to create an instance from snapshot or | ||
a source database respectively: | ||
|
||
```ts | ||
new DatabaseInstanceFromSnapshot(stack, 'Instance', { | ||
eladb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
snapshotIdentifier: 'my-snapshot', | ||
engine: rds.DatabaseInstanceEngine.Postgres, | ||
instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.Burstable2, ec2.InstanceSize.Large), | ||
vpc | ||
}); | ||
|
||
new DatabaseInstanceReadReplica(stack, 'ReadReplica', { | ||
eladb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
sourceDatabaseInstance: sourceInstance, | ||
engine: rds.DatabaseInstanceEngine.Postgres, | ||
instanceClass: new ec2.InstanceTypePair(ec2.InstanceClass.Burstable2, ec2.InstanceSize.Large), | ||
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: | ||
|
||
```ts | ||
const rule = instance.onEvent('InstanceEvent'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this an actual event name? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No it's the public onEvent(id: string, target?: events.IEventRuleTarget, options?: events.EventRuleProps) Only the generic |
||
rule.addTarget(lambdaFunction); | ||
``` | ||
|
||
### Connecting | ||
|
||
To control who can access the cluster, use the `.connections` attribute. RDS database have | ||
To control who can access the cluster/instance, use the `.connections` attribute. RDS database have | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would prefer noting "cluster or instance". Also, |
||
a default port, so you don't need to specify the port: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean it's not so much that there's a default port as it is that the RDS instance has an intrinsic (known) port. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could be that a non-standard |
||
|
||
```ts | ||
cluster.connections.allowFromAnyIpv4('Open to the world'); | ||
``` | ||
|
||
The endpoints to access your database will be available as the `.clusterEndpoint` and `.readerEndpoint` | ||
The endpoints to access your cluster database will be available as the `.clusterEndpoint` and `.readerEndpoint` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
attributes: | ||
|
||
```ts | ||
const writeAddress = cluster.clusterEndpoint.socketAddress; // "HOSTNAME:PORT" | ||
``` | ||
|
||
For an instance database: | ||
```ts | ||
const address = instance.instanceEndpoint.socketAddress; // "HOSTNAME:PORT" | ||
``` | ||
|
||
### Rotating master password | ||
When the master password is generated and stored in AWS Secrets Manager, it can be rotated automatically: | ||
When the master password is generated and stored in AWS Secrets Manager, it can be rotated automatically both for a cluster and an instance: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would rather specify when stuff applies only to |
||
|
||
[example of setting up master password rotation](test/integ.cluster-rotation.lit.ts) | ||
[example of setting up master password rotation for a cluster](test/integ.cluster-rotation.lit.ts) | ||
|
||
Rotation of the master password is also supported for an existing cluster: | ||
```ts | ||
new RotationSingleUser(stack, 'Rotation', { | ||
secret: importedSecret, | ||
engine: DatabaseEngine.Oracle, | ||
target: importedCluster, | ||
target: importedCluster, // or importedInstance | ||
vpc: importedVpc, | ||
}) | ||
``` | ||
|
@@ -87,3 +139,13 @@ The `importedSecret` must be a JSON string with the following format: | |
"port": "<optional: if not specified, default port will be used>" | ||
} | ||
``` | ||
|
||
### Metrics | ||
Database instances expose [metrics (cloudwatch.Metric)](https://github.com/awslabs/aws-cdk/blob/master/packages/%40aws-cdk/aws-cloudwatch/README.md): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not a huge fan of linking this way (especially as it'll link to a possibly un-released version of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree |
||
```ts | ||
// The number of database connections in use (average over 5 minutes) | ||
const dbConnections = instance.metricDatabaseConnections(); | ||
|
||
// The average amount of time taken per disk I/O operation (average over 1 minute) | ||
const readLatency = instance.metric('ReadLatency', { statistic: 'Average', periodSec: 60 }); | ||
``` |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* Connection endpoint of a database cluster or instance | ||
* | ||
* Consists of a combination of hostname and port. | ||
*/ | ||
export class Endpoint { | ||
/** | ||
* The hostname of the endpoint | ||
*/ | ||
public readonly hostname: string; | ||
|
||
/** | ||
* The port of the endpoint | ||
*/ | ||
public readonly port: string; | ||
|
||
/** | ||
* The combination of "HOSTNAME:PORT" for this endpoint | ||
*/ | ||
public readonly socketAddress: string; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I'd rather this is called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comes from the original implementation for the cluster construct (I just extracted to a separate file). Changing this will be breaking, ok with this? |
||
|
||
constructor(address: string, port: string) { | ||
this.hostname = address; | ||
this.port = port; | ||
this.socketAddress = `${address}:${port}`; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,14 @@ | ||
export * from './cluster'; | ||
export * from './cluster-ref'; | ||
export * from './props'; | ||
export * from './cluster-parameter-group'; | ||
export * from './parameter-group'; | ||
export * from './rotation-single-user'; | ||
export * from './database-secret'; | ||
export * from './endpoint'; | ||
export * from './option-group'; | ||
export * from './instance'; | ||
|
||
// AWS::RDS CloudFormation Resources: | ||
export * from './rds.generated'; | ||
|
||
import './rds-augmentations.generated'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use the terminology "define a
DatabaseInstance
" (instead of "create an instance").