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

feat(backup): schedule expression timezone for backup plans #27012

Closed
wants to merge 4 commits into from

Conversation

jogold
Copy link
Contributor

@jogold jogold commented Sep 5, 2023

Add timezone support for schedule expressions in backup plans.

See https://aws.amazon.com/about-aws/whats-new/2023/08/aws-backup-local-time-zone-selections/


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@github-actions github-actions bot added p2 distinguished-contributor [Pilot] contributed 50+ PRs to the CDK labels Sep 5, 2023
@aws-cdk-automation aws-cdk-automation requested a review from a team September 5, 2023 13:36
@jogold jogold changed the title feat(backup): schedule expression timezone feat(backup): schedule expression timezone for backup plans Sep 5, 2023
Copy link
Contributor

@kaizencc kaizencc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jogold, I think we should implement this similar to what we do in scheduler-alpha:

https://github.com/aws/aws-cdk/blob/main/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule-expression.ts

Of course, I still don't understand why we don't just invest time in getting the schedule class into core and I know you've tried exactly that before.

*
* @default - UTC
*/
readonly scheduleExpressionTimezone?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we export a TimeZone prop out of core.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missed that one

@@ -213,6 +224,10 @@ export class BackupPlanRule {
throw new Error('`scheduleExpression` must be of type `cron`');
}

if (props.scheduleExpressionTimezone && !props.scheduleExpression) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are some scheduleExpressions that don't make sense with a timezone, and this check ignores that.

@jogold
Copy link
Contributor Author

jogold commented Sep 5, 2023

Hi @jogold, I think we should implement this similar to what we do in scheduler-alpha:

main/packages/@aws-cdk/aws-scheduler-alpha/lib/schedule-expression.ts

Of course, I still don't understand why we don't just invest time in getting the schedule class into core and I know you've tried exactly that before.

OK, this means deprecating scheduleExpression in favor of schedule? cronExpression? other name? and you don't want to import the ScheduleExpression class of aws-scheduler-alpha in here?

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: 03c186d
  • Result: FAILED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@kaizencc
Copy link
Contributor

kaizencc commented Sep 5, 2023

Oof. I didn't realize that backup uses events.Schedule, which itself looks like its being deprecated in favor of AWS EventBridge Scheduler (or at least is pointing everyone in that direction): https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html. Of course, events.Schedule doesn't support timezone.

I think backup uses events.Schedule because of convenience. There's nothing really tying it to events besides wanting to reuse code. What's more, the docs for backup says that scheduleExpression only accepts CRON expressions so I wonder what happens if you supply events.Schedule.rate('1 minute'). Might be a bug?

I think this necessitates a hard look at how CDK does scheduling and likely means putting a Schedule class in core once and for all. Here's what I think we should do:

  • create an abstract Schedule in core, with all methods protected. idea is that each module that utilizes a schedule can implement it and expose the APIs that it supports.
  • in backup, deprecate scheduleExpression in favor of schedule, and create a new backup.Schedule class that implements core.Schedule
  • in all other modules that use schedule, we refactor the implementation to use core.Schedule and ideally there are no breaking changes here. this might be ambitious but i can't think off the top of my head if there are schedules that wouldn't be refactored cleanly.

I hate this and want to fix it once and for all. What do you think @jogold? If you agree, I can spend some time trying to get the first part right and that should kick start the other changes.

@jogold
Copy link
Contributor Author

jogold commented Sep 5, 2023

that scheduleExpression only accepts CRON expressions so I wonder what happens if you supply events.Schedule.rate('1 minute').

if (props.scheduleExpression && !/^cron/.test(props.scheduleExpression.expressionString)) {
throw new Error('`scheduleExpression` must be of type `cron`');
}

I hate this and want to fix it once and for all. What do you think @jogold? If you agree, I can spend some time trying to get the first part right and that should kick start the other changes.

Yeah, it seems to be the right thing to do.

@kaizencc
Copy link
Contributor

kaizencc commented Sep 5, 2023

Oh my that's a horrible interface in backup. What we're talking about seems like it will be an improvement across the board. Give me till the end of the week to stand up a PR to put abstract schedule in core?

@jogold
Copy link
Contributor Author

jogold commented Sep 13, 2023

Closing in favor of #27105

@jogold jogold closed this Sep 13, 2023
@jogold jogold deleted the backup-tz branch September 13, 2023 12:49
mergify bot pushed a commit that referenced this pull request Sep 20, 2023
My latest attempt at schedule unification across modules. 

The following modules use a version of schedule, which this PR aims to unify:

- aws-scheduler-alpha
- aws-events
- aws-application-autoscaling
- aws-autoscaling
- aws-synthetics-alpha
- aws-backup

The idea is to have a single source of truth, `core.Schedule` that is exposed and meant to be extended by modules that use a schedule. This is to avoid breaking changes -- every module that currently exports a schedule class continues to do so. Each module can customize their schedule class to its liking, for example, whether or not to support `schedule.at` or `cronOptions.timeZone`.

This PR will fix inconsistencies like:

  - `backup.scheduleExpression` depending on `events.Schedule`, which is semi-deprecated by the Events team (they want people to use the Schedule class in `aws-scheduler-alpha`). 
  - `aws-scheduler-alpha` depending on `events.Schedule` as well.
  - `backup.scheduleExpression` allowing `schedule.rate(duration)` to be specified (synth-time error) when we know that backup schedules only can be cron expressions.
  - having to implement the new `timeZone` property in all instances of schedules
  - avoids us from having to perform maintenance in multiple places like #19197
  - `timeZone` property existing directly on a construct when it only pertains to `cron` expressions. This is an anomaly because we typically do not want construct-level properties to only be impactful depending on other properties. [See superseded PRs]


Challenges:

  - subtle differences in expressions that are accepted. This is solved by `core.Schedule` only exposing `protected` APIs, which are then picked by the consuming modules to be exposed as `public`.
  - subtle difference in `cron` expressions accepted. I do some magic in `aws-autoscaling` to get the cron expression returned there to be as expected.

Supersedes #27052 and #27012

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
distinguished-contributor [Pilot] contributed 50+ PRs to the CDK p2
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants