diff --git a/packages/@aws-cdk/aws-rds/README.md b/packages/@aws-cdk/aws-rds/README.md index cad785735dfb6..42283697f6181 100644 --- a/packages/@aws-cdk/aws-rds/README.md +++ b/packages/@aws-cdk/aws-rds/README.md @@ -12,7 +12,7 @@ -```ts +```ts nofixture import * as rds from '@aws-cdk/aws-rds'; ``` @@ -23,6 +23,7 @@ always launch a database in a VPC. Use the `vpcSubnets` attribute to control whe your instances will be launched privately or publicly: ```ts +declare const vpc: ec2.Vpc; const cluster = new rds.DatabaseCluster(this, 'Database', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_2_08_1 }), credentials: rds.Credentials.fromGeneratedSecret('clusteradmin'), // Optional - will default to 'admin' username and generated password @@ -52,7 +53,8 @@ Your cluster will be empty by default. To add a default database upon constructi Use `DatabaseClusterFromSnapshot` to create a cluster from a snapshot: ```ts -new rds.DatabaseClusterFromSnapshot(stack, 'Database', { +declare const vpc: ec2.Vpc; +new rds.DatabaseClusterFromSnapshot(this, 'Database', { engine: rds.DatabaseClusterEngine.aurora({ version: rds.AuroraEngineVersion.VER_1_22_2 }), instanceProps: { vpc, @@ -68,6 +70,7 @@ always launch a database in a VPC. Use the `vpcSubnets` attribute to control whe your instances will be launched privately or publicly: ```ts +declare const vpc: ec2.Vpc; const instance = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.oracleSe2({ version: rds.OracleEngineVersion.VER_19_0_0_0_2020_04_R1 }), // optional, defaults to m5.large @@ -75,7 +78,7 @@ const instance = new rds.DatabaseInstance(this, 'Instance', { credentials: rds.Credentials.fromGeneratedSecret('syscdk'), // Optional - will default to 'admin' username and generated password vpc, vpcSubnets: { - subnetType: ec2.SubnetType.PRIVATE + subnetType: ec2.SubnetType.PRIVATE, } }); ``` @@ -95,6 +98,7 @@ This is the upper limit to which RDS can automatically scale the storage. More i Example for max storage configuration: ```ts +declare const vpc: ec2.Vpc; const instance = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 }), // optional, defaults to m5.large @@ -108,7 +112,8 @@ Use `DatabaseInstanceFromSnapshot` and `DatabaseInstanceReadReplica` to create a a source database respectively: ```ts -new rds.DatabaseInstanceFromSnapshot(stack, 'Instance', { +declare const vpc: ec2.Vpc; +new rds.DatabaseInstanceFromSnapshot(this, 'Instance', { snapshotIdentifier: 'my-snapshot', engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 }), // optional, defaults to m5.large @@ -116,7 +121,8 @@ new rds.DatabaseInstanceFromSnapshot(stack, 'Instance', { vpc, }); -new rds.DatabaseInstanceReadReplica(stack, 'ReadReplica', { +declare const sourceInstance: rds.DatabaseInstance; +new rds.DatabaseInstanceReadReplica(this, 'ReadReplica', { sourceDatabaseInstance: sourceInstance, instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE), vpc, @@ -136,8 +142,9 @@ The default value depends on `vpcSubnets`. It will be `true` if `vpcSubnets` is `subnetType: SubnetType.PUBLIC`, `false` otherwise. ```ts +declare const vpc: ec2.Vpc; // Setting public accessibility for DB instance -new rds.DatabaseInstance(stack, 'Instance', { +new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.mysql({ version: rds.MysqlEngineVersion.VER_8_0_19, }), @@ -149,15 +156,14 @@ new rds.DatabaseInstance(stack, 'Instance', { }); // Setting public accessibility for DB cluster -new rds.DatabaseCluster(stack, 'DatabaseCluster', { - engine: DatabaseClusterEngine.AURORA, +new rds.DatabaseCluster(this, 'DatabaseCluster', { + engine: rds.DatabaseClusterEngine.AURORA, instanceProps: { vpc, vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE, }, publiclyAccessible: true, - copyTagsToSnapshot: true, // whether to save the cluster tags when creating the snapshot. Default is 'true' }, }); ``` @@ -168,6 +174,8 @@ To define Amazon CloudWatch event rules for database instances, use the `onEvent method: ```ts +declare const instance: rds.DatabaseInstance; +declare const fn: lambda.Function; const rule = instance.onEvent('InstanceEvent', { target: new targets.LambdaFunction(fn) }); ``` @@ -179,6 +187,7 @@ An alternative username (and password) may be specified for the admin user inste The following examples use a `DatabaseInstance`, but the same usage is applicable to `DatabaseCluster`. ```ts +declare const vpc: ec2.Vpc; const engine = rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 }); new rds.DatabaseInstance(this, 'InstanceWithUsername', { engine, @@ -203,7 +212,9 @@ new rds.DatabaseInstance(this, 'InstanceWithSecretLogin', { Secrets generated by `fromGeneratedSecret()` can be customized: ```ts -const myKey = kms.Key(this, 'MyKey'); +declare const vpc: ec2.Vpc; +const engine = rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 }); +const myKey = new kms.Key(this, 'MyKey'); new rds.DatabaseInstance(this, 'InstanceWithCustomizedSecret', { engine, @@ -211,7 +222,7 @@ new rds.DatabaseInstance(this, 'InstanceWithCustomizedSecret', { credentials: rds.Credentials.fromGeneratedSecret('postgres', { secretName: 'my-cool-name', encryptionKey: myKey, - excludeCharacters: ['!&*^#@()'], + excludeCharacters: '!&*^#@()', replicaRegions: [{ region: 'eu-west-1' }, { region: 'eu-west-2' }], }), }); @@ -223,19 +234,22 @@ To control who can access the cluster or instance, use the `.connections` attrib a default port, so you don't need to specify the port: ```ts -cluster.connections.allowFromAnyIpv4('Open to the world'); +declare const cluster: rds.DatabaseCluster; +cluster.connections.allowFromAnyIpv4(ec2.Port.allTraffic(), 'Open to the world'); ``` The endpoints to access your database cluster will be available as the `.clusterEndpoint` and `.readerEndpoint` attributes: ```ts +declare const cluster: rds.DatabaseCluster; const writeAddress = cluster.clusterEndpoint.socketAddress; // "HOSTNAME:PORT" ``` For an instance database: ```ts +declare const instance: rds.DatabaseInstance; const address = instance.instanceEndpoint.socketAddress; // "HOSTNAME:PORT" ``` @@ -244,6 +258,9 @@ const address = instance.instanceEndpoint.socketAddress; // "HOSTNAME:PORT" When the master password is generated and stored in AWS Secrets Manager, it can be rotated automatically: ```ts +import * as cdk from '@aws-cdk/core'; + +declare const instance: rds.DatabaseInstance; instance.addRotationSingleUser({ automaticallyAfter: cdk.Duration.days(7), // defaults to 30 days excludeCharacters: '!@#$%^&*', // defaults to the set " %+~`#$&*()|[]{}:;<>?!'/@\"\\" @@ -255,6 +272,8 @@ instance.addRotationSingleUser({ The multi user rotation scheme is also available: ```ts +declare const instance: rds.DatabaseInstance; +declare const myImportedSecret: rds.DatabaseSecret; instance.addRotationMultiUser('MyUser', { secret: myImportedSecret, // This secret must have the `masterarn` key }); @@ -263,6 +282,7 @@ instance.addRotationMultiUser('MyUser', { It's also possible to create user credentials together with the instance/cluster and add rotation: ```ts +declare const instance: rds.DatabaseInstance; const myUserSecret = new rds.DatabaseSecret(this, 'MyUserSecret', { username: 'myuser', secretName: 'my-user-secret', // optional, defaults to a CloudFormation-generated name @@ -290,30 +310,32 @@ and a list of supported versions and limitations. The following example shows enabling IAM authentication for a database instance and granting connection access to an IAM role. ```ts -const instance = new rds.DatabaseInstance(stack, 'Instance', { +declare const vpc: ec2.Vpc; +const instance = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.mysql({ version: rds.MysqlEngineVersion.VER_8_0_19 }), vpc, iamAuthentication: true, // Optional - will be automatically set if you call grantConnect(). }); -const role = new Role(stack, 'DBRole', { assumedBy: new AccountPrincipal(stack.account) }); +const role = new iam.Role(this, 'DBRole', { assumedBy: new iam.AccountPrincipal(this.account) }); instance.grantConnect(role); // Grant the role connection access to the DB. ``` The following example shows granting connection access for RDS Proxy to an IAM role. ```ts -const cluster = new rds.DatabaseCluster(stack, 'Database', { +declare const vpc: ec2.Vpc; +const cluster = new rds.DatabaseCluster(this, 'Database', { engine: rds.DatabaseClusterEngine.AURORA, instanceProps: { vpc }, }); -const proxy = new rds.DatabaseProxy(stack, 'Proxy', { +const proxy = new rds.DatabaseProxy(this, 'Proxy', { proxyTarget: rds.ProxyTarget.fromCluster(cluster), secrets: [cluster.secret!], vpc, }); -const role = new Role(stack, 'DBProxyRole', { assumedBy: new AccountPrincipal(stack.account) }); +const role = new iam.Role(this, 'DBProxyRole', { assumedBy: new iam.AccountPrincipal(this.account) }); proxy.grantConnect(role, 'admin'); // Grant the role connection access to the DB Proxy for database user 'admin'. ``` @@ -330,13 +352,14 @@ The following example shows enabling domain support for a database instance and Directory Services. ```ts -const role = new iam.Role(stack, 'RDSDirectoryServicesRole', { +declare const vpc: ec2.Vpc; +const role = new iam.Role(this, 'RDSDirectoryServicesRole', { assumedBy: new iam.ServicePrincipal('rds.amazonaws.com'), managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonRDSDirectoryServiceAccess'), ], }); -const instance = new rds.DatabaseInstance(stack, 'Instance', { +const instance = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.mysql({ version: rds.MysqlEngineVersion.VER_8_0_19 }), vpc, domain: 'd-????????', // The ID of the domain for the instance to join. @@ -356,13 +379,15 @@ Database instances and clusters both expose metrics (`cloudwatch.Metric`): ```ts // The number of database connections in use (average over 5 minutes) +declare const instance: rds.DatabaseInstance; const dbConnections = instance.metricDatabaseConnections(); // Average CPU utilization over 5 minutes +declare const cluster: rds.DatabaseCluster; const cpuUtilization = cluster.metricCPUUtilization(); // The average amount of time taken per disk I/O operation (average over 1 minute) -const readLatency = instance.metric('ReadLatency', { statistic: 'Average', periodSec: 60 }); +const readLatency = instance.metric('ReadLatency', { statistic: 'Average', period: Duration.seconds(60) }); ``` ## Enabling S3 integration @@ -388,10 +413,14 @@ The following snippet sets up a database cluster with different S3 buckets where ```ts import * as s3 from '@aws-cdk/aws-s3'; +declare const vpc: ec2.Vpc; const importBucket = new s3.Bucket(this, 'importbucket'); const exportBucket = new s3.Bucket(this, 'exportbucket'); new rds.DatabaseCluster(this, 'dbcluster', { - // ... + engine: rds.DatabaseClusterEngine.AURORA, + instanceProps: { + vpc, + }, s3ImportBuckets: [importBucket], s3ExportBuckets: [exportBucket], }); @@ -405,18 +434,13 @@ connections to the database and improve scalability of the application. Learn mo The following code configures an RDS Proxy for a `DatabaseInstance`. ```ts -import * as cdk from '@aws-cdk/core'; -import * as ec2 from '@aws-cdk/aws-ec2'; -import * as rds from '@aws-cdk/aws-rds'; -import * as secrets from '@aws-cdk/aws-secretsmanager'; - -const vpc: ec2.IVpc = ...; -const securityGroup: ec2.ISecurityGroup = ...; -const secrets: secrets.ISecret[] = [...]; -const dbInstance: rds.IDatabaseInstance = ...; +declare const vpc: ec2.Vpc; +declare const securityGroup: ec2.SecurityGroup; +declare const secrets: secretsmanager.Secret[]; +declare const dbInstance: rds.DatabaseInstance; const proxy = dbInstance.addProxy('proxy', { - connectionBorrowTimeout: cdk.Duration.seconds(30), + borrowTimeout: Duration.seconds(30), maxConnectionsPercent: 50, secrets, vpc, @@ -430,12 +454,18 @@ store the data in highly durable storage, and manage the data with the CloudWatc instances and clusters; the types of logs available depend on the database type and engine being used. ```ts +import * as logs from '@aws-cdk/aws-logs'; +declare const myLogsPublishingRole: iam.Role; +declare const vpc: ec2.Vpc; + // Exporting logs from a cluster const cluster = new rds.DatabaseCluster(this, 'Database', { engine: rds.DatabaseClusterEngine.aurora({ version: rds.AuroraEngineVersion.VER_1_17_9, // different version class for each engine type + }), + instanceProps: { + vpc, }, - // ... cloudwatchLogsExports: ['error', 'general', 'slowquery', 'audit'], // Export all available MySQL-based logs cloudwatchLogsRetention: logs.RetentionDays.THREE_MONTHS, // Optional - default is to never expire logs cloudwatchLogsRetentionRole: myLogsPublishingRole, // Optional - a role will be created if not provided @@ -447,7 +477,7 @@ const instance = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3, }), - // ... + vpc, cloudwatchLogsExports: ['postgresql'], // Export the PostgreSQL logs // ... }); @@ -460,9 +490,10 @@ Amazon RDS uses option groups to enable and configure these features. An option that are available for a particular Amazon RDS DB instance. ```ts -const vpc: ec2.IVpc = ...; -const securityGroup: ec2.ISecurityGroup = ...; -new rds.OptionGroup(stack, 'Options', { +declare const vpc: ec2.Vpc; +declare const securityGroup: ec2.SecurityGroup; + +new rds.OptionGroup(this, 'Options', { engine: rds.DatabaseInstanceEngine.oracleSe2({ version: rds.OracleEngineVersion.VER_19, }), @@ -489,10 +520,7 @@ Aurora Serverless clusters can specify scaling properties which will be used to automatically scale the database cluster seamlessly based on the workload. ```ts -import * as ec2 from '@aws-cdk/aws-ec2'; -import * as rds from '@aws-cdk/aws-rds'; - -const vpc = new ec2.Vpc(this, 'myrdsvpc'); +declare const vpc: ec2.Vpc; const cluster = new rds.ServerlessCluster(this, 'AnotherCluster', { engine: rds.DatabaseClusterEngine.AURORA_POSTGRESQL, @@ -532,11 +560,7 @@ You can access your Aurora Serverless DB cluster using the built-in Data API. Th The following example shows granting Data API access to a Lamba function. ```ts -import * as ec2 from '@aws-cdk/aws-ec2'; -import * as lambda from '@aws-cdk/aws-lambda'; -import * as rds from '@aws-cdk/aws-rds'; - -const vpc = new ec2.Vpc(this, 'MyVPC'); +declare const vpc: ec2.Vpc; const cluster = new rds.ServerlessCluster(this, 'AnotherCluster', { engine: rds.DatabaseClusterEngine.AURORA_MYSQL, @@ -544,16 +568,17 @@ const cluster = new rds.ServerlessCluster(this, 'AnotherCluster', { enableDataApi: true, // Optional - will be automatically set if you call grantDataApiAccess() }); +declare const code: lambda.Code; const fn = new lambda.Function(this, 'MyFunction', { runtime: lambda.Runtime.NODEJS_12_X, handler: 'index.handler', - code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), + code, environment: { CLUSTER_ARN: cluster.clusterArn, - SECRET_ARN: cluster.secret.secretArn, + SECRET_ARN: cluster.secret!.secretArn, }, }); -cluster.grantDataApiAccess(fn) +cluster.grantDataApiAccess(fn); ``` **Note**: To invoke the Data API, the resource will need to read the secret associated with the cluster. diff --git a/packages/@aws-cdk/aws-rds/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-rds/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..7e78fde1372a1 --- /dev/null +++ b/packages/@aws-cdk/aws-rds/rosetta/default.ts-fixture @@ -0,0 +1,18 @@ +// Fixture with packages imported, but nothing else +import { Duration, SecretValue, Stack } from '@aws-cdk/core'; +import { Construct } from 'constructs'; +import ec2 = require('@aws-cdk/aws-ec2'); +import rds = require('@aws-cdk/aws-rds'); +import targets = require('@aws-cdk/aws-events-targets'); +import lambda = require('@aws-cdk/aws-lambda'); +import kms = require('@aws-cdk/aws-kms'); +import iam = require('@aws-cdk/aws-iam'); +import secretsmanager = require('@aws-cdk/aws-secretsmanager'); + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +}