Skip to content

Commit

Permalink
feat(rds): add support for setting public accessibility (aws#12164)
Browse files Browse the repository at this point in the history
Closes aws#12093


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
saudkhanzada authored Dec 28, 2020
1 parent 6be8500 commit b8f48e5
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 4 deletions.
34 changes: 34 additions & 0 deletions packages/@aws-cdk/aws-rds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,40 @@ Creating a "production" Oracle database instance with option and parameter group

[example of setting up a production oracle instance](test/integ.instance.lit.ts)

## Setting Public Accessibility

You can set public accessibility for the database instance or cluster using the `publiclyAccessible` property.
If you specify `true`, it creates an instance with a publicly resolvable DNS name, which resolves to a public IP address.
If you specify `false`, it creates an internal instance with a DNS name that resolves to a private IP address.
The default value depends on `vpcSubnets`.
It will be `true` if `vpcSubnets` is `subnetType: SubnetType.PUBLIC`, `false` otherwise.

```ts
// Setting public accessibility for DB instance
new rds.DatabaseInstance(stack, 'Instance', {
engine: rds.DatabaseInstanceEngine.mysql({
version: rds.MysqlEngineVersion.VER_8_0_19,
}),
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE,
},
publiclyAccessible: true,
});

// Setting public accessibility for DB cluster
new rds.DatabaseCluster(stack, 'DatabaseCluster', {
engine: DatabaseClusterEngine.AURORA,
instanceProps: {
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE,
},
publiclyAccessible: true,
},
});
```

## Instance events

To define Amazon CloudWatch event rules for database instances, use the `onEvent`
Expand Down
5 changes: 2 additions & 3 deletions packages/@aws-cdk/aws-rds/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -687,8 +687,6 @@ function createInstances(cluster: DatabaseClusterNew, props: DatabaseClusterBase
props.clusterIdentifier != null ? `${props.clusterIdentifier}instance${instanceIndex}` :
undefined;

const publiclyAccessible = instanceProps.vpcSubnets && instanceProps.vpcSubnets.subnetType === ec2.SubnetType.PUBLIC;

const instance = new CfnDBInstance(cluster, `Instance${instanceIndex}`, {
// Link to cluster
engine: props.engine.engineType,
Expand All @@ -697,7 +695,8 @@ function createInstances(cluster: DatabaseClusterNew, props: DatabaseClusterBase
dbInstanceIdentifier: instanceIdentifier,
// Instance properties
dbInstanceClass: databaseInstanceType(instanceType),
publiclyAccessible,
publiclyAccessible: instanceProps.publiclyAccessible ??
(instanceProps.vpcSubnets && instanceProps.vpcSubnets.subnetType === ec2.SubnetType.PUBLIC),
enablePerformanceInsights: enablePerformanceInsights || instanceProps.enablePerformanceInsights, // fall back to undefined if not set
performanceInsightsKmsKeyId: instanceProps.performanceInsightEncryptionKey?.keyArn,
performanceInsightsRetentionPeriod: enablePerformanceInsights
Expand Down
9 changes: 8 additions & 1 deletion packages/@aws-cdk/aws-rds/lib/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,13 @@ export interface DatabaseInstanceNewProps {
* @default - None
*/
readonly s3ExportBuckets?: s3.IBucket[];

/**
* Indicates whether the DB instance is an internet-facing instance.
*
* @default - `true` if `vpcSubnets` is `subnetType: SubnetType.PUBLIC`, `false` otherwise
*/
readonly publiclyAccessible?: boolean;
}

/**
Expand Down Expand Up @@ -704,7 +711,7 @@ abstract class DatabaseInstanceNew extends DatabaseInstanceBase implements IData
preferredBackupWindow: props.preferredBackupWindow,
preferredMaintenanceWindow: props.preferredMaintenanceWindow,
processorFeatures: props.processorFeatures && renderProcessorFeatures(props.processorFeatures),
publiclyAccessible: this.vpcPlacement && this.vpcPlacement.subnetType === ec2.SubnetType.PUBLIC,
publiclyAccessible: props.publiclyAccessible ?? (this.vpcPlacement && this.vpcPlacement.subnetType === ec2.SubnetType.PUBLIC),
storageType,
vpcSecurityGroups: securityGroups.map(s => s.securityGroupId),
maxAllocatedStorage: props.maxAllocatedStorage,
Expand Down
7 changes: 7 additions & 0 deletions packages/@aws-cdk/aws-rds/lib/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ export interface InstanceProps {
* @default - true
*/
readonly deleteAutomatedBackups?: boolean;

/**
* Indicates whether the DB instance is an internet-facing instance.
*
* @default - `true` if `vpcSubnets` is `subnetType: SubnetType.PUBLIC`, `false` otherwise
*/
readonly publiclyAccessible?: boolean;
}

/**
Expand Down
74 changes: 74 additions & 0 deletions packages/@aws-cdk/aws-rds/test/test.cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1764,6 +1764,80 @@ export = {

test.done();
},

'can set public accessibility for database cluster with instances in private subnet'(test: Test) {
// GIVEN
const stack = testStack();
const vpc = new ec2.Vpc(stack, 'VPC');

// WHEN
new DatabaseCluster(stack, 'Database', {
engine: DatabaseClusterEngine.AURORA,
instanceProps: {
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE,
},
publiclyAccessible: true,
},
});
// THEN
expect(stack).to(haveResource('AWS::RDS::DBInstance', {
Engine: 'aurora',
PubliclyAccessible: true,
}));

test.done();
},

'can set public accessibility for database cluster with instances in public subnet'(test: Test) {
// GIVEN
const stack = testStack();
const vpc = new ec2.Vpc(stack, 'VPC');

// WHEN
new DatabaseCluster(stack, 'Database', {
engine: DatabaseClusterEngine.AURORA,
instanceProps: {
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC,
},
publiclyAccessible: false,
},
});
// THEN
expect(stack).to(haveResource('AWS::RDS::DBInstance', {
Engine: 'aurora',
PubliclyAccessible: false,
}));

test.done();
},

'database cluster instances in public subnet should by default have publiclyAccessible set to true'(test: Test) {
// GIVEN
const stack = testStack();
const vpc = new ec2.Vpc(stack, 'VPC');

// WHEN
new DatabaseCluster(stack, 'Database', {
engine: DatabaseClusterEngine.AURORA,
instanceProps: {
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC,
},
},
});
// THEN
expect(stack).to(haveResource('AWS::RDS::DBInstance', {
Engine: 'aurora',
PubliclyAccessible: true,
}));

test.done();
},
};

function testStack() {
Expand Down
38 changes: 38 additions & 0 deletions packages/@aws-cdk/aws-rds/test/test.instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1204,4 +1204,42 @@ export = {

test.done();
},

'can set publiclyAccessible to false with public subnets'(test: Test) {
new rds.DatabaseInstance(stack, 'Instance', {
engine: rds.DatabaseInstanceEngine.mysql({
version: rds.MysqlEngineVersion.VER_8_0_19,
}),
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC,
},
publiclyAccessible: false,
});

expect(stack).to(haveResource('AWS::RDS::DBInstance', {
PubliclyAccessible: false,
}));

test.done();
},

'can set publiclyAccessible to true with private subnets'(test: Test) {
new rds.DatabaseInstance(stack, 'Instance', {
engine: rds.DatabaseInstanceEngine.mysql({
version: rds.MysqlEngineVersion.VER_8_0_19,
}),
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE,
},
publiclyAccessible: true,
});

expect(stack).to(haveResource('AWS::RDS::DBInstance', {
PubliclyAccessible: true,
}));

test.done();
},
};

0 comments on commit b8f48e5

Please sign in to comment.