Skip to content

Commit

Permalink
fix(secretsmanager): rotation resource creation can fail due to race …
Browse files Browse the repository at this point in the history
…condition (#26512)

Setting up a `RotationSchedule` with `rotationLambda` could cause failures due to the lambda invoking permission and the`RotationSchedule` being created concurrently.

This fix adds a dependency to ensure the policy is created first and to prevent race conditions.

Closes #26481.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
lpizzinidev authored Aug 18, 2023
1 parent 3305d4f commit 94e48c6
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@
"RotationRules": {
"AutomaticallyAfterDays": 30
}
}
},
"DependsOn": [
"LambdaInvokeN0a2GKfZP0JmDqDEVhhu6A0TUv3NyNbk4YMFKNc69846677"
]
},
"SecretPolicy06C9821C": {
"Type": "AWS::SecretsManager::ResourcePolicy",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as kms from 'aws-cdk-lib/aws-kms';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as cdk from 'aws-cdk-lib';
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
import * as integ from '@aws-cdk/integ-tests-alpha';

class TestStack extends cdk.Stack {
constructor(scope: cdk.App, id: string) {
Expand All @@ -24,5 +25,11 @@ class TestStack extends cdk.Stack {
}

const app = new cdk.App();
new TestStack(app, 'cdk-integ-secret-lambda-rotation');

const stack = new TestStack(app, 'cdk-integ-secret-lambda-rotation');

new integ.IntegTest(app, 'cdk-integ-secret-lambda-rotation-test', {
testCases: [stack],
});

app.synth();
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ export class RotationSchedule extends Resource {
);
}

props.rotationLambda.grantInvoke(new iam.ServicePrincipal('secretsmanager.amazonaws.com'));
const grant = props.rotationLambda.grantInvoke(new iam.ServicePrincipal('secretsmanager.amazonaws.com'));
grant.applyBefore(this);

props.rotationLambda.addToRolePolicy(
new iam.PolicyStatement({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -629,3 +629,25 @@ describe('manual rotations', () => {
checkRotationNotSet(Duration.millis(0));
});
});

test('rotation schedule should have a dependency on lambda permissions', () => {
// GIVEN
const secret = new secretsmanager.Secret(stack, 'Secret');
const rotationLambda = new lambda.Function(stack, 'Lambda', {
runtime: lambda.Runtime.NODEJS_14_X,
code: lambda.Code.fromInline('export.handler = event => event;'),
handler: 'index.handler',
});

// WHEN
secret.addRotationSchedule('RotationSchedule', {
rotationLambda,
});

// THEN
Template.fromStack(stack).hasResource('AWS::SecretsManager::RotationSchedule', {
DependsOn: [
'LambdaInvokeN0a2GKfZP0JmDqDEVhhu6A0TUv3NyNbk4YMFKNc69846677',
],
});
});

0 comments on commit 94e48c6

Please sign in to comment.