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

aws_secretsmanager: RotationSchedule cron expression support #24062

Open
2 tasks
vobarian opened this issue Feb 7, 2023 · 4 comments
Open
2 tasks

aws_secretsmanager: RotationSchedule cron expression support #24062

vobarian opened this issue Feb 7, 2023 · 4 comments
Labels
@aws-cdk/aws-secretsmanager Related to AWS Secrets Manager feature-request A feature should be added or improved. p3

Comments

@vobarian
Copy link

vobarian commented Feb 7, 2023

Describe the feature

Secrets Manager and CloudFormation support using a cron schedule expression for secret rotation:

Maybe I'm missing it, but I cannot find equivalent functionality in CDK. It looks like only setting a rotation period is supported:

Request: Support cron schedule expressions in RotationSchedule, SecretRotation, and Secret#addRotationSchedule.

See: #19980

Use Case

I would like to control more precisely when secret rotation happens, and this functionality exists in the underlying service but is not exposed in CDK.

Proposed Solution

Similar to the CloudFormation resource, a schedule property could be added to the relevant props interfaces alongside automaticallyAfter. The type of this property would be a flexible schedule object similar to aws_events.Schedule.

Unfortunately, this results in an awkward interface where one but not both of the schedule or automaticallyAfter properties is required. A better solution would be to have a single property that supports either rate or cron expression type. For example automaticallyAfter could accept Duration | Schedule. However then the name of that prop would be awkward. Unfortunately I can't think of a great way to express that interface in a backwards-compatible way. The ideal would be to just have a schedule property without automaticallyAfter but that would not be backwards-compatible.

Other Information

Use CfnRotationSchedule L1 as a workaround. Unfortunately it requires manually setting up the permissions for the rotation function as well.

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

CDK version used

2.63.2

Environment details (OS name and version, etc.)

macOS 12.6.1

@vobarian vobarian added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Feb 7, 2023
@github-actions github-actions bot added the @aws-cdk/aws-secretsmanager Related to AWS Secrets Manager label Feb 7, 2023
@PritamSangani
Copy link

PritamSangani commented Feb 9, 2023

Another approach to the proposed solution is to expose 2 new props in the RotationSchedule construct.

One called windowDuration (of type Duration) the other called schedule (of type Schedule).

windowDuration would map to the duration prop in the RotationRules property within the L1 construct and schedule would map to scheduleExpression.

Looking at the docs for the L1 construct, it seems you can't pass both the automaticallyAfter and the scheduleExpression prop so there would also need to be a check to make sure both props are not passed.

@pahud pahud added p2 and removed needs-triage This issue or PR still needs to be triaged. labels Feb 16, 2023
@rpawlaszek
Copy link

For now you can use property overrides. So in this case one can write:

    declare const schedule: Schedule;

    const cfnSchedule = rotationSchedule.node.defaultChild as CfnRotationSchedule;
    cfnSchedule.addPropertyOverride('RotationRules.ScheduleExpression', schedule.expressionString);
    cfnSchedule.addPropertyDeletionOverride('RotationRules.AutomaticallyAfterDays');

And the solution could be simply adding the other parameter schedule with a check if both automaticallyAfter and schedule exist that would add an error annotation if they do.

@rpawlaszek
Copy link

rpawlaszek commented Nov 24, 2023

Or a yet another approach. As both things are down below RotationRules and it's either-or there could be a property rotationRule

and a class with two static methods onSchedule(schedule: Schedule, rotationWindow?: Duration); and automaticallyAfter(days: Duration; rotationWindow?: Duration); and the usage could be like:

declare const stack: Stack;
declare const everySixHours: Schedule;
declare const threeDays: Duration;

const rotation1Schedule = new RotationSchedule(stack, 'Rotation1Schedule', {
    ...
    rotationRule: RotationRule.onSchedule(everySixHours)
});

const rotation2Schedule = new RotationSchedule(stack, 'Rotation1Schedule', {
    ...
    rotationRule: RotationRule.automaticallyAfter(threeDays)
});

It would then remove the ambiguity.

@mengmann
Copy link

For anyone struggeling with a workaround for Layer2 construct SecretRotation:

Although the Layer 2 construct SecretRotation takes a schedule from automaticallyAfter property, behind the scenes the creation of the schedule is delegated to the Layer 2 construct Secret and this already synths a property ScheduleExpression. So you need to access the RotationSchedule node from the Secret construct and then override the value for the ScheduleExpression property from there:

    const schedule: Schedule;

    const mySecret = new secretsManager.Secret()
    new secretsManager.SecretRotation(this, `SecretRotation`, {
      secret: mySecret,
      application: secretsmanager.SecretRotationApplication.MYSQL_ROTATION_MULTI_USER,
      vpc: props.vpc,
      vpcSubnets: props.subnets,
      target: this.instance,
      excludeCharacters: ' %+~`#$&*()|[]{}:;<>?!\'/@"\\',
    });

    if (props.secretRotationScheduleExpression) {
      const cfnSecretRotationSchedule = databaseSecret.node.findAll().find((child) => {
        return child instanceof CfnRotationSchedule;
      }) as CfnRotationSchedule;
      if (cfnSecretRotationSchedule) {
        cfnSecretRotationSchedule.addPropertyOverride('RotationRules.ScheduleExpression', schedule.expressionString);
        cfnSecretRotationSchedule.addPropertyDeletionOverride('RotationRules.AutomaticallyAfterDays');
      } else {
        throw new Error('CfnRotationSchedule not found for mySecret');
      }
    }

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 feature-request A feature should be added or improved. p3
Projects
None yet
Development

No branches or pull requests

5 participants