Skip to content

Commit

Permalink
feat(rds): dual-stack mode support (#22596)
Browse files Browse the repository at this point in the history
This PR adds dual-stack mode support to RDS instances and clusters.

### Aurora
- Working with a DB cluster in a VPC  
  https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html
- CloudFormation AWS::RDS::DBCluster  
  https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbcluster.html#cfn-rds-dbcluster-networktype

```ts
declare const vpc: ec2.Vpc; // VPC and subnets must have IPv6 CIDR blocks
const cluster = new rds.DatabaseCluster(this, 'Database', {
  engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_3_02_1 }),
  instanceProps: {
    vpc,
    publiclyAccessible: false,
  },
  networkType: rds.NetworkType.DUAL,
});
```

### RDS
- Working with a DB instance in a VPC  
  https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html
- CloudFormation AWS::RDS::DBInstance  
  https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbinstance.html#cfn-rds-dbinstance-networktype

```ts
declare const vpc: ec2.Vpc; // VPC and subnets must have IPv6 CIDR blocks
const instance = new rds.DatabaseInstance(this, 'Instance', {
  engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_14_4 }),
  vpc,
  networkType: rds.NetworkType.DUAL,
  publiclyAccessible: false,
});
```

Note: CDK cannot check whether the specified VPC and subnets have actually IPv6 CIDR blocks because `ec2.IVpc` and `ec2.ISubnet` does not have ipv6 attributes. (cf. #19525)

----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
Tietew authored Oct 26, 2022
1 parent 243b4ad commit 89a7365
Show file tree
Hide file tree
Showing 23 changed files with 3,813 additions and 1 deletion.
30 changes: 30 additions & 0 deletions packages/@aws-cdk/aws-rds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ 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.

To use dual-stack mode, specify `NetworkType.DUAL` on the `networkType` property:

```ts
declare const vpc: ec2.Vpc; // VPC and subnets must have IPv6 CIDR blocks
const cluster = new rds.DatabaseCluster(this, 'Database', {
engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_3_02_1 }),
instanceProps: {
vpc,
publiclyAccessible: false,
},
networkType: rds.NetworkType.DUAL,
});
```

For more information about dual-stack mode, see [Working with a DB cluster in a VPC](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html).

Use `DatabaseClusterFromSnapshot` to create a cluster from a snapshot:

```ts
Expand Down Expand Up @@ -129,6 +145,20 @@ const instance = new rds.DatabaseInstance(this, 'Instance', {
});
```

To use dual-stack mode, specify `NetworkType.DUAL` on the `networkType` property:

```ts
declare const vpc: ec2.Vpc; // VPC and subnets must have IPv6 CIDR blocks
const instance = new rds.DatabaseInstance(this, 'Instance', {
engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_14_4 }),
vpc,
networkType: rds.NetworkType.DUAL,
publiclyAccessible: false,
});
```

For more information about dual-stack mode, see [Working with a DB instance in a VPC](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html).

Use `DatabaseInstanceFromSnapshot` and `DatabaseInstanceReadReplica` to create an instance from snapshot or
a source database respectively:

Expand Down
9 changes: 9 additions & 0 deletions packages/@aws-cdk/aws-rds/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { IClusterEngine } from './cluster-engine';
import { DatabaseClusterAttributes, IDatabaseCluster } from './cluster-ref';
import { DatabaseSecret } from './database-secret';
import { Endpoint } from './endpoint';
import { NetworkType } from './instance';
import { IParameterGroup, ParameterGroup } from './parameter-group';
import { applyDefaultRotationOptions, defaultDeletionProtection, renderCredentials, setupS3ImportExport, helperRemovalPolicy, renderUnless } from './private/util';
import { BackupProps, Credentials, InstanceProps, PerformanceInsightRetention, RotationSingleUserOptions, RotationMultiUserOptions, SnapshotCredentials } from './props';
Expand Down Expand Up @@ -280,6 +281,13 @@ interface DatabaseClusterBaseProps {
* @default - true
*/
readonly copyTagsToSnapshot?: boolean;

/**
* The network type of the DB instance.
*
* @default - IPV4
*/
readonly networkType?: NetworkType;
}

/**
Expand Down Expand Up @@ -481,6 +489,7 @@ abstract class DatabaseClusterNew extends DatabaseClusterBase {
associatedRoles: clusterAssociatedRoles.length > 0 ? clusterAssociatedRoles : undefined,
deletionProtection: defaultDeletionProtection(props.deletionProtection, props.removalPolicy),
enableIamDatabaseAuthentication: props.iamAuthentication,
networkType: props.networkType,
// Admin
backtrackWindow: props.backtrackWindow?.toSeconds(),
backupRetentionPeriod: props.backup?.retention?.toDays(),
Expand Down
23 changes: 23 additions & 0 deletions packages/@aws-cdk/aws-rds/lib/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,21 @@ export enum StorageType {
IO1 = 'io1'
}

/**
* The network type of the DB instance.
*/
export enum NetworkType {
/**
* IPv4 only network type.
*/
IPV4 = 'IPV4',

/**
* Dual-stack network type.
*/
DUAL = 'DUAL'
}

/**
* Construction properties for a DatabaseInstanceNew
*/
Expand Down Expand Up @@ -617,6 +632,13 @@ export interface DatabaseInstanceNewProps {
* @default - `true` if `vpcSubnets` is `subnetType: SubnetType.PUBLIC`, `false` otherwise
*/
readonly publiclyAccessible?: boolean;

/**
* The network type of the DB instance.
*
* @default - IPV4
*/
readonly networkType?: NetworkType;
}

/**
Expand Down Expand Up @@ -759,6 +781,7 @@ abstract class DatabaseInstanceNew extends DatabaseInstanceBase implements IData
maxAllocatedStorage: props.maxAllocatedStorage,
domain: this.domainId,
domainIamRoleName: this.domainRole?.roleName,
networkType: props.networkType,
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "21.0.0",
"files": {
"b5ff1147ce210b6a8be6120310d71e1a1bcb6c64b802b268e0b994bb80eb9ced": {
"source": {
"path": "aws-cdk-rds-cluster-dual-integ.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "b5ff1147ce210b6a8be6120310d71e1a1bcb6c64b802b268e0b994bb80eb9ced.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Loading

0 comments on commit 89a7365

Please sign in to comment.