简体   繁体   中英

Running AWS CDK custom resource for database setup after RDS instance is created

How can I trigger a Lambda function using AWS CDK after an RDS instance is up?

I am setting up a system with an RDS instance and an EKS cluster using AWS CDK and Typescript. After the RDS instance is created, I would like to set up some users in the database instance to be used by microservices on EKS.

I created a Custom Resource backed by a Lambda function for this, also implemented in Typescript. The lambda function retrieves the secret generated by CDK for the RDS instance plus some secrets for my database users, connects to the database and creates the database users. Ideally, the custom resource runs after the database instance is up and before the microservices are installed. How can I achieve this?

I haven't found a way to explicitly declare the dependency and my Lambda does not technically require a dependency (other than using secret.grantRead(lambda) ). Just running a retry loop in Lambda until everything is up will likely not work thanks to the long creation times. Any code snippets/examples/... greatly appreciated, I have only found references about the general approach so far.

Update with details in reply to @jogold: With

    const database = new rds.DatabaseInstance(this, 'db', {
      instanceIdentifier: conf.systemName,
      engine: rds.DatabaseInstanceEngine.POSTGRES,
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MICRO),
      masterUsername: MASTER_USER,
      allocatedStorage: 20, maxAllocatedStorage: 100,
      multiAz: conf.isProduction,
      storageEncrypted: true,
      backupRetention: cdk.Duration.days(7),
      deletionProtection: false, 
      vpc, securityGroups: [ rdsSG ]
    });

CDK will generate a secret with some more or less random name with the access credentials to the database. I tried attaching the secret directly to my Lambda:

    new cdk.CustomResource(this, 'preinstall', { 
      serviceToken: preinstallProvider.serviceToken,
      properties: { secret: database.secret }
    });

But that gives me

    Error: Resolution error: Resolution error: Trying to resolve() a Construct at /Resources/${Token[td000.preinstall.Default.LogicalID.221]}/Properties/dbSecret/node/_actualNode.

Also, it looks like the interface ISecret doesn't have the ID/name of the secret, so I wouldn't know what to do with it in the Lambda.

CDK will usually try to guess the dependencies for you and ensure that they're created in the correct order. Where this doesn't work (as in your example), you can explicity declare that one resource depends on another. For example:

const customResource = new cdk.CustomResource(this, 'preinstall', { 
  serviceToken: preinstallProvider.serviceToken,
  properties: { secret: database.secret }
});

customResource.node.addDependency(database);

See the docs for more details https://docs.aws.amazon.com/cdk/api/latest/docs/core-readme.html#construct-dependencies

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM