You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用CDK(TypeScript)为已有Aurora MySQL集群添加数据库?

问题描述

我们正从Terraform切换到TypeScript版CDK,已成功创建包含2个实例的Aurora MySQL集群,集群创建的代码转换过程很顺利,但找不到用CDK为集群添加数据库的相关文档。

Terraform中是通过MySQL Provider来创建数据库的,示例代码如下:

# Configure the MySQL provider
provider "mysql" {
  endpoint = "my-database.example.com:3306"
  username = "app-user"
  password = "app-password"
}

# Create a Database
resource "mysql_database" "app" {
  name = "my_awesome_app"
}

多方查找后仍未找到CDK中为已有集群添加数据库的等效构造和流程,请问这在CDK中是否可行?


更新:CDK创建集群的代码

new rds.DatabaseCluster(
    this,
    `db-cluster`,
    {
        clusterIdentifier: `cluster`,
        credentials: rds.Credentials.fromSecret(...),
        engine: rds.DatabaseClusterEngine.auroraMysql({
            version: rds.AuroraMysqlEngineVersion.of(...)
        }),
        instances: 2,
        instanceProps: {
            vpc,
            securityGroups: [dbSecurityGroup],
            instanceType: new ec2.InstanceType(...)
        },
        subnetGroup,
        instanceIdentifierBase: 'instance-',
    })

解决方案

CDK本身没有提供直接创建RDS数据库(Schema)的L2/L3构造,因为这属于数据库内部操作,不属于AWS基础设施资源范畴。要实现类似Terraform的效果,有几种可行方式:

1. 使用自定义资源(Custom Resource)执行SQL

这是最贴合基础设施即代码的方式,通过自定义资源调用Lambda函数,连接到Aurora集群执行CREATE DATABASE语句。

核心实现思路

  • 创建Lambda函数:从Secret Manager获取数据库凭证,连接集群,执行创建数据库的SQL(判断数据库不存在时再创建)。
  • 定义CDK自定义资源:关联上述Lambda函数,传入集群端点、数据库名称、Secret ARN等参数。

CDK代码片段

// 1. 创建用于创建数据库的Lambda函数
const createDbLambda = new lambda.Function(this, 'CreateDbLambda', {
  runtime: lambda.Runtime.NODEJS_18_X,
  code: lambda.Code.fromAsset('lambda'),
  handler: 'create-db.handler',
  vpc: vpc,
  securityGroups: [dbSecurityGroup],
  environment: {
    SECRET_ARN: credentials.secretArn,
    CLUSTER_ENDPOINT: cluster.clusterEndpoint.hostname,
    DB_NAME: 'my_awesome_app'
  }
});

// 2. 赋予Lambda必要权限:读取Secret、连接RDS
credentials.secret.grantRead(createDbLambda);
dbSecurityGroup.connections.allowFrom(createDbLambda, ec2.Port.tcp(3306));

// 3. 创建自定义资源触发Lambda执行
new customresources.AwsCustomResource(this, 'CreateDatabase', {
  onUpdate: {
    service: 'Lambda',
    action: 'invoke',
    parameters: {
      FunctionName: createDbLambda.functionName,
      InvocationType: 'RequestResponse'
    },
    physicalResourceId: customresources.PhysicalResourceId.of(`create-db-${Date.now()}`)
  }
});

Lambda核心逻辑(lambda/create-db.js)

const mysql = require('mysql2/promise');
const { SecretsManagerClient, GetSecretValueCommand } = require('@aws-sdk/client-secrets-manager');

const client = new SecretsManagerClient({ region: process.env.AWS_REGION });

exports.handler = async () => {
  // 从Secret Manager获取数据库凭证
  const secret = await client.send(new GetSecretValueCommand({ SecretId: process.env.SECRET_ARN }));
  const { username, password } = JSON.parse(secret.SecretString);

  // 连接数据库并创建Schema
  const connection = await mysql.createConnection({
    host: process.env.CLUSTER_ENDPOINT,
    user: username,
    password: password,
    port: 3306
  });

  await connection.execute(`CREATE DATABASE IF NOT EXISTS ${process.env.DB_NAME}`);
  await connection.end();

  return { status: 'success' };
};

2. 使用RDS初始化脚本(User Data)

如果是在创建集群时一并初始化数据库,可以通过instanceProps的initScript参数传入SQL脚本,脚本会在实例首次启动时执行。但这种方式仅适用于集群创建阶段,无法用于已有集群的后续数据库添加。

代码片段

instanceProps: {
  // ...其他配置项
  initScript: fs.readFileSync('./init-db.sql', 'utf8')
}

init-db.sql内容:

CREATE DATABASE IF NOT EXISTS my_awesome_app;

3. 手动执行或CI/CD流程补充

如果不需要在基础设施部署时自动创建,也可以在集群部署完成后,通过CI/CD工具(如GitHub Actions、GitLab CI)连接数据库执行SQL,或者手动通过MySQL客户端创建数据库。


内容的提问来源于stack exchange,提问作者CKT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 03:15:43