Applicable when
- We need to create RDS cluster that will be using existing VPC (e.g.: from Central).
Implementation
Create VPC construct:
import { CfnSecurityGroup, IVpc, Vpc } from '@aws-cdk/aws-ec2';
import { CfnOutput, Construct } from '@aws-cdk/core';
import { RdsOutputs } from '../model/rds-outputs.enum';
export class VTagVpc extends Construct {
public readonly instance: IVpc;
public readonly securityGroup: CfnSecurityGroup;
constructor(scope: Construct) {
super(scope, 'Network');
this.instance = Vpc.fromLookup(this, 'VPC', {
vpcId: scope.node.tryGetContext('defaultVpcId'),
});
// Create security group
this.securityGroup = new CfnSecurityGroup(this, 'VisualTagVpcSecurityGroup', {
groupDescription: 'Created from CDK',
groupName: 'visualtag-vpc-security-group',
vpcId: this.instance.vpcId,
securityGroupIngress: [
{
cidrIp: '10.0.0.0/8',
ipProtocol: 'TCP',
fromPort: 3306,
toPort: 3306,
},
],
});
}
}
Create Secret Construct:
import { ISecret, Secret } from '@aws-cdk/aws-secretsmanager';
import { Construct } from '@aws-cdk/core';
export class VTagSecret extends Construct {
public readonly credentials: ISecret;
constructor(scope: Construct) {
super(scope, 'Secret');
this.credentials = Secret.fromSecretArn(
this,
'VisualTagCredentials',
String(this.node.tryGetContext('secretCredentialsArn'))
);
}
}
Create RDS Construct:
import { CfnDBCluster, CfnDBClusterParameterGroup, CfnDBInstance, CfnDBSubnetGroup } from '@aws-cdk/aws-rds';
import { CfnOutput, Construct } from '@aws-cdk/core';
import { RdsOutputs } from '../model/rds-outputs.enum';
import { VTagSecret } from './vtag-secret';
import { VTagVpc } from './vtag-vpc';
export class VTagRds extends Construct {
public readonly clusterParameterGroup: CfnDBClusterParameterGroup;
private readonly cluster: CfnDBCluster;
constructor(scope: Construct, private readonly secrets: VTagSecret, private readonly vpc: VTagVpc) {
super(scope, 'Rds');
this.clusterParameterGroup = new CfnDBClusterParameterGroup(this, 'Params', {
description: 'Aurora',
family: this.node.tryGetContext('rdsClusterFamily'),
parameters: {
character_set_client: 'utf8',
character_set_connection: 'utf8',
character_set_database: 'utf8',
character_set_filesystem: 'utf8',
character_set_results: 'utf8',
character_set_server: 'utf8',
collation_connection: 'utf8_general_ci',
},
});
const subnetIds = [...this.vpc.instance.privateSubnets, ...this.vpc.instance.publicSubnets].map(
subnet => subnet.subnetId
);
// Fixes AWS Error: No default subnet detected in VPC. Please contact AWS Support to recreate default Subnets.
const subnetGroup = new CfnDBSubnetGroup(this, 'SubnetGroup', {
subnetIds,
dbSubnetGroupDescription: 'Created from CDK',
dbSubnetGroupName: `visualtag-${this.vpc.instance.vpcId}`,
});
this.cluster = new CfnDBCluster(this, 'Cluster', {
engine: this.node.tryGetContext('rdsEngine'),
engineVersion: this.node.tryGetContext('rdsEngine'),
masterUsername: this.secrets.credentials.secretValueFromJson('rdsUsername').toString(),
masterUserPassword: this.secrets.credentials.secretValueFromJson('rdsPassword').toString(),
dbClusterParameterGroupName: this.clusterParameterGroup.ref,
dbSubnetGroupName: subnetGroup.ref,
vpcSecurityGroupIds: [this.vpc.securityGroup.attrGroupId],
});
// No need to store output in variable
// tslint:disable-next-line:no-unused-expression
new CfnDBInstance(this, 'Instance', {
dbInstanceClass: 'db.r5.large',
dbClusterIdentifier: this.cluster.ref,
dbSubnetGroupName: subnetGroup.ref,
engine: this.cluster.engine,
publiclyAccessible: false,
});
}
}
Now bind everything together in a stack:
import { App, Stack } from '@aws-cdk/core';
import { VTagRds } from '../construct/vtag-rds';
import { VTagSecret } from '../construct/vtag-secret';
import { VTagVpc } from '../construct/vtag-vpc';
import { ENVIRONMENT, RDS_STACK_NAME } from '../util/const';
export class RdsStack extends Stack {
public readonly vpc: VTagVpc;
public readonly secrets: VTagSecret;
public readonly rds: VTagRds;
constructor(app: App) {
super(app, RDS_STACK_NAME, { env: ENVIRONMENT });
this.vpc = new VTagVpc(this);
this.secrets = new VTagSecret(this);
this.rds = new VTagRds(this, this.secrets, this.vpc);
}
}
Comments
0 comments
Please sign in to leave a comment.