-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(rds): secret rotation application times out before rotation completes #17265
Comments
Update: rotation still times out after canceling the previous rotation and setting the timeout of the Lambda function to 15 minutes:
|
Hey @asterikx, I was under the impression that the applications took care of the rotation, and that you shouldn't really trigger them yourself. Is that not your experience - has this worked before? Thanks, |
Thanks Adam! I'm using Aurora Serverless V1 (MySQL-compatible) since 1+ year with a single master user and weekly secret rotation. I just had a look at the CloudWatch logs, rotation failed every single time (5 attempts each time, with each attempt timing out after 30 secs). In fact, I also never had to change the password to connect to the DB during development ... I'm currently migrating to RDS PostgreSQL. I created a secondary user/role, following this blog post on best practices. Since I created this role with the very unsecure password I remember reading somewhere that secret rotation is triggered once immediately after deploying the secret rotation application. This matches what I've found, however, initial rotation did also time out so that the unsecure password I agree with you that I shouldn't really trigger the secret rotation myself, since the secret rotation application is supposed to do that for me ;) |
Hi @asterikx, You should be able to trigger the rotation manually. The "application" deploys a Lambda function that can be triggered manually from the Secrets Manager console. From your code I see that the the "secondary secret rotation" is acting on the master secret ( Now for your second secret, you should follow the multi user rotation scheme, see It's also possible to create user credentials together with the instance/cluster and add rotation: // create secondary DB secret (used by apps to connect to DB)
const dbUserSecret = new rds.DatabaseSecret(this, 'DbUserSecret', {
username: 'app_user',
masterSecret: db.secret, // the master secret of your DB
});
// attach secondary DB secret
const dbUserSecretAttached = dbUserSecret.attach(db);
instance.addRotationMultiUser('MyUser', { // Add rotation using the multi user scheme
secret: dbUserSecretAttached,
}); |
Hi @jogold. Sorry, I messed up when putting together the code for this issue. I used Here's the complete code: const dbAdminUserSecret = new rds.DatabaseSecret(this, 'DbAdminUserSecret', {
username: 'postgres',
});
const dbUserSecret = new rds.DatabaseSecret(this, 'DbUserSecret', {
username: 'app_user',
masterSecret: dbAdminUserSecret,
});
const db = new rds.DatabaseInstance(this, 'Database', {
engine: rds.DatabaseInstanceEngine.postgres({
version: rds.PostgresEngineVersion.VER_13_4,
}),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE4_GRAVITON, ec2.InstanceSize.MICRO),
credentials: rds.Credentials.fromSecret(dbAdminUserSecret),
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC,
},
});
db.addRotationSingleUser({
automaticallyAfter: cdk.Duration.days(30),
});
const dbUserSecretAttached = dbUserSecret.attach(db);
new secretsmanager.SecretRotation(this, 'DatabaseUserSecretRotation', {
application: secretsmanager.SecretRotationApplication.POSTGRES_ROTATION_SINGLE_USER,
secret: dbUserSecretAttached,
target: db,
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC,
},
automaticallyAfter: cdk.Duration.days(30),
}); As for the the multi user scheme, I'm curious why I should use it over the single user scheme? Is it purely to prevent auth failures during secret rotation? Either way, I see the single user rotation on the master secret failing for 1+ year of my Serverless cluster and also failing on the master secret of the RDS instance in this issue. I'm happy to help, let me know how I can assist. |
OK, I suspect the time out to come from connectivity issues between your Lambda and your DB or between your Lambda and internet. Can you check the security groups for both the Lambda and the DB (those are normally created and configured for you by the CDK)? Can you also confirm that your Lambda has internet connectivity in the subnet where it is deployed? It needs to access the Secrets Manager API. |
@jogold Thanks! The rotation Lambda indeed did not have internet connectivity! From my findings, the rotation Lambda is put in the same subnet than the DB. Secret rotation only works if the target DB is located in a private subnet ( For isolated subnets, internet connectivity is blocked by design. For public subnets, internet connectivity is not possible as the ENI attached to a Lambda function does not have a public IP (packets are dropped at the IGW). I think, the methods What do you think? |
I got secret rotation to work by explicitly creating the secret rotation applications and placing them into the private subnet of my VPC: const dbAdminUserSecret = new rds.DatabaseSecret(this, 'DbAdminUserSecret', {
username: 'postgres',
});
const dbUserSecret = new rds.DatabaseSecret(this, 'DbUserSecret', {
username: 'app_user',
masterSecret: dbAdminUserSecret,
});
const db = new rds.DatabaseInstance(this, 'Database', {
engine: rds.DatabaseInstanceEngine.postgres({
version: rds.PostgresEngineVersion.VER_13_4,
}),
credentials: rds.Credentials.fromSecret(dbAdminUserSecret),
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC, // <-- database is put into PUBLIC subnet
},
});
new secretsmanager.SecretRotation(this, 'DbAdminUserSecretRotation', {
application: secretsmanager.SecretRotationApplication.POSTGRES_ROTATION_SINGLE_USER,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
secret: db.secret!,
target: db,
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT, // <-- rotation function is put into PRIVATE subnet
},
});
const dbUserSecretAttached = dbUserSecret.attach(db);
new secretsmanager.SecretRotation(this, 'DbUserSecretRotation', {
application: secretsmanager.SecretRotationApplication.POSTGRES_ROTATION_MULTI_USER,
secret: dbUserSecretAttached,
masterSecret: db.secret,
target: db,
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT, // <-- rotation function is put into PRIVATE subnet
},
}); Also: for rotation to succeed for the secondary secret, you have to create the secondary user in the DB with the password set to the Secrets Manager generated password of the secondary secret (otherwise the rotation function will not be able to login in the DB) |
@asterikx Actually you can deploy the rotation Lambda anywhere if you use a VPC endpoint for Secrets Manager. To close this issue I suggest the following:
@skinny85 wdyt? I can work on the PR for this. |
@jogold your proposal sounds good to me 👍🏻 Regarding the VPC endpoint for Secrets Manager, it might be useful mentioning pricing in the docs. Pricing was ultimately the reason why I decided to use a NAT instance (EC2 t4g instance). |
@jogold sure, that would be amazing 🙂. |
…et rotation Add options to configure vpc subnet placement and Secrets Manager API endpoint for the rotation Lambda function. This is required in some VPC configurations where the database is placed in subnets without internet connectivity. Closes aws#17265
…et rotation (#17363) Add options to configure vpc subnet placement and Secrets Manager API endpoint for the rotation Lambda function. This is required in some VPC configurations where the database is placed in subnets without internet connectivity. Closes #17265 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
|
…et rotation (#17363) Add options to configure vpc subnet placement and Secrets Manager API endpoint for the rotation Lambda function. This is required in some VPC configurations where the database is placed in subnets without internet connectivity. Closes #17265 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
…et rotation (aws#17363) Add options to configure vpc subnet placement and Secrets Manager API endpoint for the rotation Lambda function. This is required in some VPC configurations where the database is placed in subnets without internet connectivity. Closes aws#17265 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
There's a bug in VPC selection for addRotationMultiUser. Even if you pass in props for the subnet type to place the rotation lambda, it will always get placed in the same subnets as the cluster. See https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-rds/lib/cluster.ts line 611 for the addRotationMultiUser function. Notice how the '...options' line gets overridden by the cluster subnets. The addRotationSingleUser function doesn't have this problem because the options are injected after the defaults. See the same file as above. Created new issue to track: #19233 |
What is the problem?
The secret rotation application times out before rotation completes and rotation fails.
Reproduction Steps
I log into the DB using the master user
postgres
and the generated password and create the secondary userapp_user
with passwordsecret_passwd
.I'm now able to log into the DB using the user
app_user
with passwordsecret_passwd
.Next, I trigger secret rotation for the secondary DB secret:
Alternatively: under
AWS Console > AWS Secrets Manager > Secrets > DbUserSecretXXXXXXXX-yyyyyyyyyyyy
, pressRotate secret immediately
What did you expect to happen?
After triggering secret rotation, I can log into the DB using the newly generated password and the old password no longer works.
What actually happened?
Secret rotation is triggered successfully, however, I'm not able to login with the newly generated password. The old password
secret_passwd
still works.Looking at the CloudWatch Logs of the secret rotation application, I can see that the function repeatedly times out:
Triggering rotation again gives the following error:
CDK CLI Version
1.130.0
Framework Version
1.130.0
Node.js Version
v14.17.6
OS
macOS 12.0.1
Language
Typescript
Language Version
4.4.4
Other information
No response
The text was updated successfully, but these errors were encountered: