Per documentation https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-rds.DatabaseInstance.html:
"By default, the master password will be generated and stored in AWS Secrets Manager with auto-generated description."
In my case during provisioning of DatabaseInstance, CDK generated a secret with a name = LogicalId from CFN template. Would be nice to be able to set a name for a secret which will be generated by AWS CDK and stored in AWS Secrets Manager.
Also applies to other resources which are provisioned as part of higher lever constructs.
Hi,
I believe this to be a bug not a feature request. I think you should be able to supply the secret as per the code below. However, the cloudformation script that are created based on this fail as they do not correctly handle the referencing between the secret and the database as the key can not exist until the database is created. This isn't an issue when the secret isn't specified as it is handled correctly.
export class CdkDbStack extends cdk.Stack {
readonly secret: secretsManager.ISecret;
readonly testGocdRDSInstance: rds.DatabaseInstance;
constructor(scope: cdk.App, id: string, props: SharedStackProps) {
super(scope, id, props);
const databaseUsername = 'admin';
this.secret = new secretsManager.Secret(this, 'TestDBCredentialsSecret', {
secretName: `test-rds-server-credentials`,
generateSecretString: {
secretStringTemplate: JSON.stringify({
username: databaseUsername,
}),
generateStringKey: 'password'
}
});
const testRDSInstance = new rds.DatabaseInstance(this, 'test-rds-db-Instance', {
engine: rds.DatabaseInstanceEngine.POSTGRES,
// micro database should be available on free tier
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MICRO),
masterUsername: databaseUsername,
masterUserPassword: this.secret.secretValue,
vpc: props.vpc,
// Placement via the subnet defined for the VPC
vpcPlacement: {subnetGroupName: 'Database'},
// Alternative mapping if only one of the subnet types exists
// vpcPlacement: {subnetType: SubnetType.ISOLATED },
storageType: rds.StorageType.GP2,
storageEncrypted: true,
allocatedStorage: 20, // GiB
backupRetention: Duration.days(5),
maxAllocatedStorage: 30, //GiB
instanceIdentifier: 'test-ci-database',
// None production we can live without multiple availability zones
multiAz: false,
autoMinorVersionUpgrade: true
});
}
The differences between the generated cloudformation scripts:
Specified secret, not working.
"MasterUserPassword": {
"Fn::Join": [
"",
[
"{{resolve:secretsmanager:",
{
"Ref": "TestCiGoServerDBCredentialsSecret9741AE3F"
},
":SecretString:::}}"
]
]
},
Unspecified key, working:
"MasterUserPassword": {
"Fn::Join": [
"",
[
"{{resolve:secretsmanager:",
{
"Ref": "testcidbInstanceSecret66362675"
},
":SecretString:password::}}"
]
]
},
There are also differences in the secret resource.
I've discovered that if you pass the secret value from the JSON as shown below:
masterUserPassword: this.secret.secretValueFromJson('password'),
Then the deployment works and you can successfully achieve the feature requested by the original poster and the deployment works. I'd suggest that this reinforced that this is a bug with the compiler.
Hi, I'd like to help out with this if no one is currently working on it.
This applies to Aurora clusters as well, as both use Credentials()
@kochie - I don't believe anyone else is currently working on it. Please feel free to take a shot and post the PR, and let us know if you'd like any guidance.
As the login
/credentials
interface of RDS changed between the original request and now, I'd say there are now two options for how to go about this:
secretName
to DatabaseSecret
, and use Credentials.fromSecret
to use it with a DB. This would involve just the change to the DatabaseSecret
class and props.const secret = new DatabaseSecret(this, 'Secret', {
username: 'admin',
secretName: 'myDbSecret',
});
const instance = new rds.DatabaseInstance(this, 'Instance', {
credentials: rds.Credentials.fromSecret(secret),
...
});
secretName
as an option for CredentialsFromUsernameOptions
to use with the Credentials.fromUsername
method. This would entail changes to Credentials
as well as each of its consumers (DatabaseInstance
, DatabaseCluster
, and ServerlessCluster
).const instance = new rds.DatabaseInstance(this, 'Instance', {
credentials: rds.Credentials.fromUsername('admin', { secretName: 'myDbSecret'} ),
...
});
Any progress on this?
Most helpful comment
Hi, I'd like to help out with this if no one is currently working on it.