aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.68k stars 3.93k forks source link

(aws-rds): database connection string in generated secret (secret manager) #23613

Open snebjorn opened 1 year ago

snebjorn commented 1 year ago

Describe the feature

It would be handy to have a "ready to use" connection string. Currently it's a hassle to transform the RDS secret from the secret manager into a connection string. It involves unsafeUnwrap and generating a secret in the Systems Manager Parameter Store based on the values in the Secret Manager.

Use Case

var database = new DatabaseInstance(stack, 'my-database', {
  // rest omitted ...
});

new ApplicationLoadBalancedFargateService(stack, 'my-fargate', {
  taskImageOptions: {
    secrets: [{
      'ConnectionStrings__MyDatabase': Secret.fromSecretsManager(database.secret, 'connectionString')
    }]
  },
  // rest omitted ...
});

Proposed Solution

A default connection string for each supported database type would nice.

// default SQL Server connection string
Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;

However connection strings are highly configurable. So it would be ideal to be able to alter it. It's actually necessary as the Database=...; parameter is application specific and required.

new DatabaseInstance(stack, 'my-database', {
  // rest omitted ... 
  credentials: Credentials.fromGeneratedSecret('admin', {
    // {{key}} refers to keys in the generated json secret
    // note `Database=MyDatabaseName` is hardcoded as it's not in the secret manager
    connectionStringTemplate: 'Server={{host}},{{port}};Database=MyDatabaseName;User Id={{username}};Password={{password}};'
  }),
});

This way it would be easy to alter the connection sting:

{
  connectionStringTemplate: 'Server={{host}},{{port}};Database=MyDatabaseName;User Id={{username}};Password={{password}};MultipleActiveResultSets=True;'
}

A version of Credentials.fromGeneratedSecret that only accepts the options would also be welcome, because then the connectionStringTemplate can be configured without hardcoding a username.

Credentials.fromGeneratedSecret({
  connectionStringTemplate: 'Server={{host}},{{port}};Database=MyDatabaseName;User Id={{username}};Password={{password}};'
})

Other Information

Another solution could be to extract a configurable connection string from the secret manager:

Secret.connectionStringFromSecretsManager(database.secret, {
  // {{key}} refers to keys in the generated json secret
  // note `Database=MyDatabaseName` is hardcoded as it's not in the secret manager
  connectionStringTemplate: 'Server={{host}},{{port}};Database=MyDatabaseName;User Id={{username}};Password={{password}};'
})

Found other people with the same issue:

Acknowledgements

CDK version used

2.55.0

Environment details (OS name and version, etc.)

Not relevant

pahud commented 1 year ago

Yes this seems to be a very handy feature. I am making it p2 now and any PR submission would be highly appreciated.

mdvertola commented 4 months ago

+1 on this, I would love to see this added.