Skip to content
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

(secretsmanager): RotationSchedule resource creation race causes some stack deployments to fail #26481

Closed
gavllew opened this issue Jul 24, 2023 · 4 comments · Fixed by #26512
Labels
@aws-cdk/aws-secretsmanager Related to AWS Secrets Manager bug This issue is a bug. effort/small Small work item – less than a day of effort p2

Comments

@gavllew
Copy link

gavllew commented Jul 24, 2023

Describe the bug

When using CDK to set up a Secrets Manager RotationSchedule, creation of the AWS::SecretsManager::RotationSchedule resource can fail (in a small proportion of deployments) with the following error:

Secrets Manager cannot invoke the specified Lambda function. Ensure that the function policy grants access to the principal secretsmanager.amazonaws.com. (Service: AWSSecretsManager; Status Code: 400; Error Code: AccessDeniedException

From looking at the Stack events, I can see that the Lambda Invoke permission and the RotationSchedule are being created at the same time, so it's down to luck whether the RotationSchedule's test invoke succeeds or fails, though in most cases it seems to succeed. An explicit dependency to ensure the Lambda resource policy is created first would improve the deployment reliability.

Expected Behavior

The deployment succeeds reliably.

Current Behavior

The deployment failed with the above error in 2 out of 18 deployments.

Reproduction Steps

Create a new typescript CDK project:

mkdir cdk-bug; cd cdk-bug
cdk init --language=typescript

Replace lib/cdk-bug-stack.ts with the following:

import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import { Secret } from 'aws-cdk-lib/aws-secretsmanager';
import { Construct } from 'constructs';

export class CdkBugStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const secret = new Secret(this, "Secret", {});
    const rotationLambda = new lambda.Function(this, "RotationLambda", {
      runtime: lambda.Runtime.NODEJS_18_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline('exports.handler = async () => { console.log("Fake rotation lambda"); };'),
    });

    secret.addRotationSchedule("RotationSchedule", {
      rotationLambda,
    });
  }
}

A cdk synth shows that the SecretRotationSchedule49AED07D resource has no dependency on the AWS::Lambda::Permission resource RotationLambdaInvokeN0a2GKfZP0JmDqDEVhhu6A0TUv3NyNbk4YMFKNc852E0E9A.

Possible Solution

Add an explicit dependency to ensure the Lambda resource policy is created before the RotationSchedule.

Additional Information/Context

No response

CDK CLI Version

2.88.0 (build 5d497f9)

Framework Version

2.87.0

Node.js Version

v18.17.0

OS

MacOS 13.4.1 (c) (22F770820d)

Language

Typescript

Language Version

TypeScript (5.1.6)

Other information

No response

@gavllew gavllew added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jul 24, 2023
@github-actions github-actions bot added the @aws-cdk/aws-secretsmanager Related to AWS Secrets Manager label Jul 24, 2023
@gavllew gavllew changed the title (secretsmanager): (short issue description) (secretsmanager): RotationSchedule resource creation race causes some stack deployments to fail Jul 24, 2023
@peterwoodworth peterwoodworth added p2 effort/small Small work item – less than a day of effort and removed needs-triage This issue or PR still needs to be triaged. labels Jul 24, 2023
@peterwoodworth
Copy link
Contributor

Thanks, this makes sense. We add the permission here in the code, but there isn't a convenient way I can see without escape hatches for the code to access the permission from here

props.rotationLambda.grantInvoke(new iam.ServicePrincipal('secretsmanager.amazonaws.com'));

@gavllew
Copy link
Author

gavllew commented Jul 24, 2023

The grantInvoke returns a Grant instance, which implements IDependable, and offers an applyBefore method.

@peterwoodworth
Copy link
Contributor

Ah neat, I never knew about this feature

lpizzinidev added a commit to lpizzinidev/aws-cdk that referenced this issue Aug 18, 2023
mergify bot added a commit to lpizzinidev/aws-cdk that referenced this issue Aug 18, 2023
@mergify mergify bot closed this as completed in #26512 Aug 18, 2023
mergify bot pushed a commit that referenced this issue Aug 18, 2023
…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*
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-secretsmanager Related to AWS Secrets Manager bug This issue is a bug. effort/small Small work item – less than a day of effort p2
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants