Skip to content

Commit 728b234

Browse files
authored
Merge branch 'main' into cf_template_wording_SUP-4542
2 parents fcfa916 + 46ac6fa commit 728b234

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,60 @@ To enable resource limits with custom values, include these parameters in your C
9292
- Resource limits are disabled by default
9393
- Values can be specified as percentages or absolute values (for memory-related parameters)
9494

95+
## Scheduled Scaling
96+
97+
The Elastic CI Stack supports time-based scaling to automatically adjust the minimum number of instances based on your team's working hours. This feature helps optimize costs by scaling down during off-hours while allowing users the ability to proactively scale up capacity ahead of expected increasing capacity requirements.
98+
99+
### Configuration Parameters
100+
101+
| Parameter | Description | Default |
102+
|--------------------------|------------------------------------------------------|----------------------|
103+
| `EnableScheduledScaling` | Enable scheduled scaling actions | `false` |
104+
| `ScheduleTimezone` | Timezone for scheduled actions | `UTC` |
105+
| `ScaleUpSchedule` | Cron expression for scaling up | `0 8 * * MON-FRI` |
106+
| `ScaleUpMinSize` | MinSize when scaling up | `1` |
107+
| `ScaleDownSchedule` | Cron expression for scaling down | `0 18 * * MON-FRI` |
108+
| `ScaleDownMinSize` | MinSize when scaling down | `0` |
109+
110+
### Example Configuration
111+
112+
To enable scheduled scaling that maintains a minimum of 10 ASG instances during business hours (8 AM - 6 PM, Eastern Time) and 2 ASG instances during off-hours:
113+
114+
```json
115+
{
116+
"Parameters": {
117+
"EnableScheduledScaling": "true",
118+
"ScheduleTimezone": "America/New_York",
119+
"ScaleUpSchedule": "0 8 * * MON-FRI",
120+
"ScaleUpMinSize": "10",
121+
"ScaleDownSchedule": "0 18 * * MON-FRI",
122+
"ScaleDownMinSize": "2"
123+
}
124+
}
125+
```
126+
127+
### Schedule Format
128+
129+
Scheduled scaling uses [AWS Auto Scaling cron expressions](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-scheduled-scaling.html#scheduled-scaling-cron) with the format:
130+
```
131+
minute hour day-of-month month day-of-week
132+
```
133+
134+
Common examples:
135+
- `0 8 * * MON-FRI` - 8:00 AM on weekdays
136+
- `0 18 * * MON-FRI` - 6:00 PM on weekdays
137+
- `0 9 * * SAT` - 9:00 AM on Saturdays
138+
- `30 7 * * 1-5` - 7:30 AM Monday through Friday (using numbers)
139+
140+
### Timezone Support
141+
142+
The `ScheduleTimezone` parameter supports [IANA timezone names](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-scheduled-scaling.html#scheduled-scaling-timezone) such as:
143+
- `America/New_York` (Eastern Time)
144+
- `America/Los_Angeles` (Pacific Time)
145+
- `Europe/London` (Greenwich Mean Time)
146+
- `Asia/Tokyo` (Japan Standard Time)
147+
- `UTC` (Coordinated Universal Time)
148+
95149
## Development
96150

97151
To get started with customizing your own stack, or contributing fixes and features:

templates/aws-stack.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ Metadata:
8181
- ImageIdParameter
8282
- InstanceOperatingSystem
8383
- InstanceTypes
84+
- CpuCredits
8485
- EnableInstanceStorage
8586
- MountTmpfsAtTmp
8687
- AgentsPerInstance
@@ -129,6 +130,12 @@ Metadata:
129130
- ScalerEventSchedulePeriod
130131
- ScalerMinPollInterval
131132
- ScalerEnableExperimentalElasticCIMode
133+
- EnableScheduledScaling
134+
- ScheduleTimezone
135+
- ScaleUpSchedule
136+
- ScaleUpMinSize
137+
- ScaleDownSchedule
138+
- ScaleDownMinSize
132139

133140
- Label:
134141
default: Cost Allocation Configuration
@@ -248,6 +255,45 @@ Parameters:
248255
- "false"
249256
Default: "false"
250257

258+
EnableScheduledScaling:
259+
Description: Enable scheduled scaling to automatically adjust MinSize based on time-based schedules
260+
Type: String
261+
AllowedValues:
262+
- "true"
263+
- "false"
264+
Default: "false"
265+
266+
ScheduleTimezone:
267+
Description: "Timezone for scheduled scaling actions (only used when EnableScheduledScaling is true). See AWS documentation for supported formats: https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-scheduled-scaling.html#scheduled-scaling-timezone (America/New_York, UTC, Europe/London, etc.)"
268+
Type: String
269+
Default: "UTC"
270+
271+
ScaleUpSchedule:
272+
Description: "Cron expression for when to scale up (only used when EnableScheduledScaling is true). See AWS documentation for format details: https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-scheduled-scaling.html#scheduled-scaling-cron (\"0 8 * * MON-FRI\" for 8 AM weekdays)"
273+
Type: String
274+
Default: "0 8 * * MON-FRI"
275+
AllowedPattern: '^[0-9*,-/]+ [0-9*,-/]+ [0-9*,-/]+ [0-9*,-/]+ [0-9A-Za-z*,-/]+$'
276+
ConstraintDescription: "Must be a valid cron expression (5 fields: minute hour day-of-month month day-of-week)"
277+
278+
ScaleUpMinSize:
279+
Description: MinSize to set when the ScaleUpSchedule is triggered (applied at the time specified in ScaleUpSchedule, only used when EnableScheduledScaling is true). Cannot exceed MaxSize.
280+
Type: Number
281+
Default: 1
282+
MinValue: 0
283+
284+
ScaleDownSchedule:
285+
Description: "Cron expression for when to scale down (only used when EnableScheduledScaling is true). See AWS documentation for format details: https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-scheduled-scaling.html#scheduled-scaling-cron (\"0 18 * * MON-FRI\" for 6 PM weekdays)"
286+
Type: String
287+
Default: "0 18 * * MON-FRI"
288+
AllowedPattern: '^[0-9*,-/]+ [0-9*,-/]+ [0-9*,-/]+ [0-9*,-/]+ [0-9A-Za-z*,-/]+$'
289+
ConstraintDescription: "Must be a valid cron expression (5 fields: minute hour day-of-month month day-of-week)"
290+
291+
ScaleDownMinSize:
292+
Description: MinSize to set when the ScaleDownSchedule is triggered (applied at the time specified in ScaleDownSchedule, only used when EnableScheduledScaling is true)
293+
Type: Number
294+
Default: 0
295+
MinValue: 0
296+
251297
ScaleOutCooldownPeriod:
252298
Description: Cooldown period in seconds before allowing another scale-out event. Prevents rapid scaling and reduces costs from frequent instance launches.
253299
Type: Number
@@ -530,6 +576,14 @@ Parameters:
530576
AllowedPattern: "^[\\w-\\.]+(,[\\w-\\.]*){0,24}$"
531577
ConstraintDescription: "must contain 1-25 instance types separated by commas. No space before/after the comma."
532578

579+
CpuCredits:
580+
Description: Credit option for CPU usage of burstable instances. Sets the CreditSpecification.CpuCredits property in the LaunchTemplate for T-class instance types (t2, t3, t3a, t4g).
581+
Type: String
582+
AllowedValues:
583+
- standard
584+
- unlimited
585+
Default: "unlimited"
586+
533587
MaxSize:
534588
Description: Maximum number of instances. Controls cost ceiling and prevents runaway scaling.
535589
Type: Number
@@ -1190,6 +1244,13 @@ Conditions:
11901244
- !Equals [ !Select [ 0, !Split [ ".", !Ref InstanceTypes ] ], "t4g" ]
11911245
- !Equals [ !Select [ 0, !Split [ ".", !Ref InstanceTypes ] ], "x2gd" ]
11921246

1247+
UsingBurstableInstances:
1248+
!Or
1249+
- !Equals [ !Select [ 0, !Split [ ".", !Ref InstanceTypes ] ], "t2" ]
1250+
- !Equals [ !Select [ 0, !Split [ ".", !Ref InstanceTypes ] ], "t3" ]
1251+
- !Equals [ !Select [ 0, !Split [ ".", !Ref InstanceTypes ] ], "t3a" ]
1252+
- !Equals [ !Select [ 0, !Split [ ".", !Ref InstanceTypes ] ], "t4g" ]
1253+
11931254
UseStackNameForInstanceName:
11941255
!Equals [ !Ref InstanceName, "" ]
11951256

@@ -1202,6 +1263,9 @@ Conditions:
12021263
- !Equals [ !Ref RootVolumeType, "io2" ]
12031264
- !Equals [ !Ref RootVolumeType, "gp3" ]
12041265

1266+
EnableScheduledScaling:
1267+
!Equals [ !Ref EnableScheduledScaling, "true" ]
1268+
12051269
Mappings:
12061270
ECRManagedPolicy:
12071271
none : { Policy: '' }
@@ -1723,6 +1787,10 @@ Resources:
17231787
Encrypted: !Ref RootVolumeEncrypted
17241788
Throughput: !If [ IsRootVolumeIsGp3, !Ref RootVolumeThroughput, !Ref "AWS::NoValue" ]
17251789
Iops: !If [ IsRootVolumeIsIo1OrIo2OrGp3, !Ref RootVolumeIops, !Ref "AWS::NoValue" ]
1790+
CreditSpecification: !If
1791+
- UsingBurstableInstances
1792+
- CpuCredits: !Ref CpuCredits
1793+
- !Ref "AWS::NoValue"
17261794
TagSpecifications:
17271795
- ResourceType: instance
17281796
Tags:
@@ -2064,6 +2132,26 @@ Resources:
20642132
AutoScalingReplacingUpdate:
20652133
WillReplace: true
20662134

2135+
ScheduledScaleUpAction:
2136+
Condition: EnableScheduledScaling
2137+
Type: AWS::AutoScaling::ScheduledAction
2138+
Properties:
2139+
AutoScalingGroupName: !Ref AgentAutoScaleGroup
2140+
ScheduledActionName: !Sub "${AWS::StackName}-ScaleUp"
2141+
Recurrence: !Ref ScaleUpSchedule
2142+
MinSize: !Ref ScaleUpMinSize
2143+
TimeZone: !Ref ScheduleTimezone
2144+
2145+
ScheduledScaleDownAction:
2146+
Condition: EnableScheduledScaling
2147+
Type: AWS::AutoScaling::ScheduledAction
2148+
Properties:
2149+
AutoScalingGroupName: !Ref AgentAutoScaleGroup
2150+
ScheduledActionName: !Sub "${AWS::StackName}-ScaleDown"
2151+
Recurrence: !Ref ScaleDownSchedule
2152+
MinSize: !Ref ScaleDownMinSize
2153+
TimeZone: !Ref ScheduleTimezone
2154+
20672155
AsgProcessSuspenderRole:
20682156
Type: AWS::IAM::Role
20692157
Properties:

0 commit comments

Comments
 (0)