constructor()

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);
    }
  }