Search code examples
amazon-web-servicesaws-cdkamazon-aurora

Aurora serverless v2 execute SQL in CDK


I'm trying to create an Aurora Serverless v2 DB cluster with CDK, and creating the database right after the cluster is provisioned. I have this code:

const dbSecurityGroup = new ec2.SecurityGroup(this, `AuroraSecurityGroup-${config.Environment}`, {
  vpc: this.vpc, // use the vpc created above
  allowAllOutbound: true, // allow outbound traffic to anywhere
})

// allow inbound traffic from anywhere to the db
dbSecurityGroup.addIngressRule(
  ec2.Peer.anyIpv4(),
  ec2.Port.tcp(5432), // allow inbound traffic on port 5432 (postgres)
  'allow inbound traffic from anywhere to the db on port 5432'
)

// create a db cluster
// https://github.com/aws/aws-cdk/issues/20197#issuecomment-1117555047

const dbCluster = new rds.DatabaseCluster(this, `DbCluster-${config.Environment}`, {
  engine: rds.DatabaseClusterEngine.auroraPostgres({
    version: rds.AuroraPostgresEngineVersion.VER_15_2,
  }),
  serverlessV2MinCapacity: config.AuroraConfig.ServerlessV2MinCapacity, //default is 0.5
  serverlessV2MaxCapacity: config.AuroraConfig.ServerlessV2MaxCapacity, // default is 2
  instances: config.AuroraConfig.Instances,
  instanceProps: {
    vpc: this.vpc,
    instanceType: new ec2.InstanceType('serverless'),
    autoMinorVersionUpgrade: true,
    publiclyAccessible: false,
    securityGroups: [dbSecurityGroup],
    vpcSubnets: this.vpc.selectSubnets({
      subnetType: ec2.SubnetType.PRIVATE_ISOLATED, // use the public subnet created above for the db
    }),
  },
  port: 5432, // use port 5432 instead of 3306
});

// add capacity to the db cluster to enable scaling
cdk.Aspects.of(dbCluster).add({
  visit(node) {
    if (node instanceof rds.CfnDBCluster) {
      node.serverlessV2ScalingConfiguration = {
        minCapacity: 0.5, // min capacity is 0.5 vCPU
        maxCapacity: 1, // max capacity is 1 vCPU (default)
      }
    }
  },
});

let dbClusterArn = `arn:aws:rds:${this.region}:${this.account}:cluster:${dbCluster.clusterIdentifier}`

const createDatabase = new cr.AwsCustomResource(this, "RDSCreateDatabase", {
  policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
    resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
  }),
  logRetention: RetentionDays.ONE_WEEK,
  onCreate: {
    service: "RDSDataService",
    action: "executeStatement",
    physicalResourceId: cr.PhysicalResourceId.of(
      dbCluster.clusterIdentifier
    ),
    parameters: {
      resourceArn: dbClusterArn,
      secretArn: dbCluster.secret?.secretArn,
      sql: "CREATE DATABASE database OWNER postgres;",
    },
  },
});
createDatabase.node.addDependency(dbCluster);
dbCluster.secret?.grantRead(createDatabase);

However, when deploying this I'm getting Received response status [FAILED] from custom resource. Message returned: HttpEndpoint is not enabled for cluster stack-dev-dbclusterdevc49f8bef-ndxhnjvzrltl . Please refer to https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html#data-api.troubleshooting

Upon some research I found that the data api is not available for Aurora Serverless V2... How should I go about creating the database?


Solution

  • You would have to create a Lambda function that runs once, just to create the database.

    Although, if you are doing all this just to create a single database in your Aurora cluster, please be aware that you could simply pass a value for the default_database_name parameter in your rds.DatabaseCluster and RDS/Aurora will create the database for you automatically when the cluster is created.