in src/index.ts [208:287]
constructor(scope: cdk.Construct, id: string, props: DatabaseProps) {
super(scope, id);
this.masterUser = props.masterUserName ?? 'admin';
// generate and store password for masterUser in the secrets manager
const masterUserSecret = new secretsmanager.Secret(this, 'DbMasterSecret', {
secretName: `${cdk.Stack.of(this).stackName}-DbMasterSecret`,
generateSecretString: {
secretStringTemplate: JSON.stringify({
username: this.masterUser,
}),
passwordLength: 12,
excludePunctuation: true,
includeSpace: false,
generateStringKey: 'password',
},
});
this.masterPassword = masterUserSecret;
const dbConnectionGroup = new SecurityGroup(this, 'DB Secuirty Group', {
vpc: props.vpc,
});
dbConnectionGroup.connections.allowInternally(Port.tcp(3306));
const dbCluster = new rds.DatabaseCluster(this, 'DBCluster', {
engine: rds.DatabaseClusterEngine.auroraMysql({
version: rds.AuroraMysqlEngineVersion.VER_2_08_1,
}),
instanceProps: {
vpc: props.vpc,
instanceType: props.instanceType ?? new InstanceType('t3.medium'),
securityGroups: [dbConnectionGroup],
},
credentials: {
username: masterUserSecret.secretValueFromJson('username').toString(),
password: masterUserSecret.secretValueFromJson('password'),
},
instances: props.instanceCapacity,
removalPolicy: cdk.RemovalPolicy.DESTROY,
});
// Workaround for bug where TargetGroupName is not set but required
let cfnDbInstance = dbCluster.node.children.find((child: any) => {
return child instanceof rds.CfnDBInstance;
}) as rds.CfnDBInstance;
// enable the RDS proxy by default
if (props.rdsProxy !== false) {
// create iam role for RDS proxy
const rdsProxyRole = new iam.Role(this, 'RdsProxyRole', {
assumedBy: new iam.ServicePrincipal('rds.amazonaws.com'),
});
// see: https://aws.amazon.com/tw/blogs/compute/using-amazon-rds-proxy-with-aws-lambda/
rdsProxyRole.addToPolicy(new iam.PolicyStatement({
actions: [
'secretsmanager:GetResourcePolicy',
'secretsmanager:GetSecretValue',
'secretsmanager:DescribeSecret',
'secretsmanager:ListSecretVersionIds',
],
resources: [masterUserSecret.secretArn],
}));
const proxyOptions: rds.DatabaseProxyOptions = {
vpc: props.vpc,
secrets: [masterUserSecret],
iamAuth: true,
dbProxyName: `${cdk.Stack.of(this).stackName}-RDSProxy`,
securityGroups: [dbConnectionGroup],
role: rdsProxyRole,
};
// create the RDS proxy
this.rdsProxy = dbCluster.addProxy('RDSProxy', proxyOptions);
// ensure DB instance is ready before creating the proxy
this.rdsProxy?.node.addDependency(cfnDbInstance);
}
}