Search code examples
typescriptaws-cdkaws-documentdb

SubnetGroup.fromSomething() for DocDB?


I am attempting to add a DocDB stack with cdk for an internal application. At my organization we are unable to create new SubnetGroups. Below is the code that failed to run. I have been looking through the docs but I don't see an option to get an existing subnet group from ARN/Name/ID etc... does this functionality exist or am I going about this wrong?

// We are unauthorized to create subnet groups
const subnetGroup = new docdb.CfnDBSubnetGroup(this, `${ProjectSettings.PROJECT_NAME}-Subnet-Group`, {
    subnetIds: [subnet1.subnetId, subnet2.subnetId],
    dbSubnetGroupName: `${ProjectSettings.PROJECT_NAME}-Subnet-Group`,
    dbSubnetGroupDescription: `${ProjectSettings.PROJECT_NAME} Subnet Group for DocumentDB`
});

const dbCluster = new docdb.CfnDBCluster(this, `${ProjectSettings.PROJECT_NAME}-Db-Cluster`, {
    storageEncrypted: true,
    availabilityZones: [ProjectSettings.AZ1_SLUG, ProjectSettings.AZ2_SLUG],
    dbClusterIdentifier: `${ProjectSettings.PROJECT_NAME}Docdb`,
    masterUsername: `${ProjectSettings.PROJECT_NAME}dbuser`,
    masterUserPassword: ProjectSettings.DB_MASTER_PASS,
    vpcSecurityGroupIds: [sg.securityGroupName],
    dbSubnetGroupName: subnetGroup.dbSubnetGroupName, //How do I query for an existing subnetgroup?
    port
});

dbCluster.addDependsOn(subnetGroup) //How do I query for an existing subnetgroup?

const dbInstance = new docdb.CfnDBInstance(this, `${ProjectSettings.PROJECT_NAME}-Db-Instance`, {
    dbClusterIdentifier: dbCluster.ref,
    autoMinorVersionUpgrade: true,
    dbInstanceClass: "db.t3.medium",
    //TODO: Change me to something else
    dbInstanceIdentifier: "development",
});
dbInstance.addDependsOn(dbCluster);

Solution

  • I ended up using the SDK to query the existing SubnetGroup name, and wrapping the cluster creation with CDK inside the callback.

    docDbSDK.describeDBSubnetGroups({}, (err, resp) => {
                if (err) throw err;
                if (resp.DBSubnetGroups) {
                    let subnetGroup = resp.DBSubnetGroups[0]
                    const dbCluster = new docdb.CfnDBCluster(this, `${ProjectSettings.PROJECT_NAME}-Db-Cluster`, {
                        storageEncrypted: true,
                        availabilityZones: [ProjectSettings.AZ1_SLUG, ProjectSettings.AZ2_SLUG],
                        dbClusterIdentifier: `${ProjectSettings.PROJECT_NAME}Docdb`,
                        masterUsername: `${ProjectSettings.PROJECT_NAME}dbuser`,
                        masterUserPassword: ProjectSettings.DB_MASTER_PASS,
                        vpcSecurityGroupIds: [sg.securityGroupName],
                        dbSubnetGroupName: subnetGroup.DBSubnetGroupName,
                        port
                    });
    
                    const dbInstance = new docdb.CfnDBInstance(this, `${ProjectSettings.PROJECT_NAME}-Db-Instance`, {
                        dbClusterIdentifier: dbCluster.ref,
                        autoMinorVersionUpgrade: true,
                        dbInstanceClass: "db.t3.medium",
                        //TODO: Change me to something else
                        dbInstanceIdentifier: "development",
                    });
                    dbInstance.addDependsOn(dbCluster);
    
                    // Add a ingress rule for the VPC CIDR
                    // TODO: Might not need to give access to the WHOLE VPC for the account...
                    sg.addIngressRule(ec2.Peer.ipv4(defaultVpc.vpcCidrBlock), ec2.Port.tcp(port));
    
                    // Found this in a how-to, testing output
                    new cdk.CfnOutput(this, `${ProjectSettings.PROJECT_NAME}-Db-URL`, {
                        value: `mongodb://${dbCluster.masterUsername}:${dbCluster.masterUserPassword}@${dbCluster.attrEndpoint}:${dbCluster.attrPort}`
                    });
                }
            })
    

    It looks like if you are creating a DBCluster with CDK you only need to reference the name of the subnetgroup.