Skip to content

Commit

Permalink
feat(applicationautoscaling): timezone for ScheduledAction (#29116)
Browse files Browse the repository at this point in the history
Closes #22645
Closes #27754

Spiritual successor of #27052

Somewhat related to #21181 but that might be another PR down the road.

@pahud ✋ Please review. I'm not particularly fond of how `aws-autoscaling` module ([here](https://github.com/aws/aws-cdk/blob/256cca4017a80f8643c5f5a5999a2ce0383eebf0/packages/aws-cdk-lib/aws-autoscaling/lib/scheduled-action.ts#L21)) is not using `cdk.TimeZone` class, hence why used it in this PR instead. I think we should we change `aws-autoscaling` implementation to do the same? It would be a breaking change... and most likely a brand new PR. LMK what you think. ✌️ 

Also, I may be slightly OCD but I kinda like better `timezone` vs `timeZone`, but I went with latter one to follow what `aws-autoscaling` did.

cc-ing @kaizencc for his input too 🙌  ... possibly related to #27105

### Reason for this change



Timezones have been supported in `AWS::ApplicationAutoScaling::ScalableTarget ScheduledAction` for a while now.

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-applicationautoscaling-scalabletarget-scheduledaction.html#cfn-applicationautoscaling-scalabletarget-scheduledaction-timezone


### Description of changes

Just added the support for `timezones` in `scalableTarget.scaleOnSchedule`

### Description of how you validated changes

Added unit tests for this feature.

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
robertd committed Feb 15, 2024
1 parent 6fbcce6 commit 8694125
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
7 changes: 5 additions & 2 deletions packages/aws-cdk-lib/aws-applicationautoscaling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ The following example scales the fleet out in the morning, and lets natural
scaling take over at night:

```ts
import { TimeZone } from 'aws-cdk-lib';
declare const resource: SomeScalableResource;

const capacity = resource.autoScaleCapacity({
Expand All @@ -187,11 +188,13 @@ const capacity = resource.autoScaleCapacity({
capacity.scaleOnSchedule('PrescaleInTheMorning', {
schedule: appscaling.Schedule.cron({ hour: '8', minute: '0' }),
minCapacity: 20,
timeZone: TimeZone.AMERICA_DENVER,
});

capacity.scaleOnSchedule('AllowDownscalingAtNight', {
schedule: appscaling.Schedule.cron({ hour: '20', minute: '0' }),
minCapacity: 1
minCapacity: 1,
timeZone: TimeZone.AMERICA_DENVER,
});
```

Expand All @@ -205,7 +208,7 @@ import * as lambda from 'aws-cdk-lib/aws-lambda';
declare const code: lambda.Code;

const handler = new lambda.Function(this, 'MyFunction', {
runtime: lambda.Runtime.PYTHON_3_7,
runtime: lambda.Runtime.PYTHON_3_12,
handler: 'index.handler',
code,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Schedule } from './schedule';
import { BasicStepScalingPolicyProps, StepScalingPolicy } from './step-scaling-policy';
import { BasicTargetTrackingScalingPolicyProps, TargetTrackingScalingPolicy } from './target-tracking-scaling-policy';
import * as iam from '../../aws-iam';
import { IResource, Lazy, Resource, withResolved } from '../../core';
import { IResource, Lazy, Resource, TimeZone, withResolved } from '../../core';

export interface IScalableTarget extends IResource {
/**
Expand Down Expand Up @@ -161,6 +161,7 @@ export class ScalableTarget extends Resource implements IScalableTarget {
maxCapacity: action.maxCapacity,
minCapacity: action.minCapacity,
},
timezone: action.timeZone?.timezoneName,
});
}

Expand Down Expand Up @@ -225,6 +226,14 @@ export interface ScalingSchedule {
* @default No new maximum capacity
*/
readonly maxCapacity?: number;

/**
* The time zone used when referring to the date and time of a scheduled action,
* when the scheduled action uses an at or cron expression.
*
* @default - UTC
*/
readonly timeZone?: TimeZone;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,38 @@ describe('scalable target', () => {
});
});

test('set timzone in scaleOnSchedule()', () => {
// GIVEN
const stack = new cdk.Stack();
const target = createScalableTarget(stack);

// WHEN
target.scaleOnSchedule('ScaleUp', {
schedule: appscaling.Schedule.cron({
hour: '8',
day: '1',
}),
maxCapacity: 50,
minCapacity: 1,
timeZone: cdk.TimeZone.AMERICA_DENVER,
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::ApplicationAutoScaling::ScalableTarget', {
ScheduledActions: [
{
ScalableTargetAction: {
MaxCapacity: 50,
MinCapacity: 1,
},
Schedule: 'cron(* 8 1 * ? *)',
ScheduledActionName: 'ScaleUp',
Timezone: 'America/Denver',
},
],
});
});

test('scheduled scaling shows warning when minute is not defined in cron', () => {
// GIVEN
const stack = new cdk.Stack();
Expand Down

0 comments on commit 8694125

Please sign in to comment.