-
Notifications
You must be signed in to change notification settings - Fork 4.1k
/
Copy pathstep-scaling-action.ts
194 lines (173 loc) · 5.4 KB
/
step-scaling-action.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import * as cdk from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnScalingPolicy } from './applicationautoscaling.generated';
import { IScalableTarget } from './scalable-target';
/**
* Properties for a scaling policy
*/
export interface StepScalingActionProps {
/**
* The scalable target
*/
readonly scalingTarget: IScalableTarget;
/**
* A name for the scaling policy
*
* @default Automatically generated name
*/
readonly policyName?: string;
/**
* How the adjustment numbers are interpreted
*
* @default ChangeInCapacity
*/
readonly adjustmentType?: AdjustmentType;
/**
* Grace period after scaling activity.
*
* For scale out policies, multiple scale outs during the cooldown period are
* squashed so that only the biggest scale out happens.
*
* For scale in policies, subsequent scale ins during the cooldown period are
* ignored.
*
* @see https://docs.aws.amazon.com/autoscaling/application/APIReference/API_StepScalingPolicyConfiguration.html
* @default No cooldown period
*/
readonly cooldown?: cdk.Duration;
/**
* Minimum absolute number to adjust capacity with as result of percentage scaling.
*
* Only when using AdjustmentType = PercentChangeInCapacity, this number controls
* the minimum absolute effect size.
*
* @default No minimum scaling effect
*/
readonly minAdjustmentMagnitude?: number;
/**
* The aggregation type for the CloudWatch metrics.
*
* @default Average
*/
readonly metricAggregationType?: MetricAggregationType;
}
/**
* Define a step scaling action
*
* This kind of scaling policy adjusts the target capacity in configurable
* steps. The size of the step is configurable based on the metric's distance
* to its alarm threshold.
*
* This Action must be used as the target of a CloudWatch alarm to take effect.
*/
export class StepScalingAction extends cdk.Construct {
/**
* ARN of the scaling policy
*/
public readonly scalingPolicyArn: string;
private readonly adjustments = new Array<CfnScalingPolicy.StepAdjustmentProperty>();
constructor(scope: Construct, id: string, props: StepScalingActionProps) {
super(scope, id);
// Cloudformation requires either the ResourceId, ScalableDimension, and ServiceNamespace
// properties, or the ScalingTargetId property, but not both.
// https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-applicationautoscaling-scalingpolicy.html
const resource = new CfnScalingPolicy(this, 'Resource', {
policyName: props.policyName || this.node.uniqueId,
policyType: 'StepScaling',
scalingTargetId: props.scalingTarget.scalableTargetId,
stepScalingPolicyConfiguration: {
adjustmentType: props.adjustmentType,
cooldown: props.cooldown && props.cooldown.toSeconds(),
minAdjustmentMagnitude: props.minAdjustmentMagnitude,
metricAggregationType: props.metricAggregationType,
stepAdjustments: cdk.Lazy.any({ produce: () => this.adjustments }),
} as CfnScalingPolicy.StepScalingPolicyConfigurationProperty,
});
this.scalingPolicyArn = resource.ref;
}
/**
* Add an adjusment interval to the ScalingAction
*/
public addAdjustment(adjustment: AdjustmentTier) {
if (adjustment.lowerBound === undefined && adjustment.upperBound === undefined) {
throw new Error('At least one of lowerBound or upperBound is required');
}
this.adjustments.push({
metricIntervalLowerBound: adjustment.lowerBound,
metricIntervalUpperBound: adjustment.upperBound,
scalingAdjustment: adjustment.adjustment,
});
}
}
/**
* How adjustment numbers are interpreted
*/
export enum AdjustmentType {
/**
* Add the adjustment number to the current capacity.
*
* A positive number increases capacity, a negative number decreases capacity.
*/
CHANGE_IN_CAPACITY = 'ChangeInCapacity',
/**
* Add this percentage of the current capacity to itself.
*
* The number must be between -100 and 100; a positive number increases
* capacity and a negative number decreases it.
*/
PERCENT_CHANGE_IN_CAPACITY = 'PercentChangeInCapacity',
/**
* Make the capacity equal to the exact number given.
*/
EXACT_CAPACITY = 'ExactCapacity',
}
/**
* How the scaling metric is going to be aggregated
*/
export enum MetricAggregationType {
/**
* Average
*/
AVERAGE = 'Average',
/**
* Minimum
*/
MINIMUM = 'Minimum',
/**
* Maximum
*/
MAXIMUM = 'Maximum'
}
/**
* An adjustment
*/
export interface AdjustmentTier {
/**
* What number to adjust the capacity with
*
* The number is interpeted as an added capacity, a new fixed capacity or an
* added percentage depending on the AdjustmentType value of the
* StepScalingPolicy.
*
* Can be positive or negative.
*/
readonly adjustment: number;
/**
* Lower bound where this scaling tier applies.
*
* The scaling tier applies if the difference between the metric
* value and its alarm threshold is higher than this value.
*
* @default -Infinity if this is the first tier, otherwise the upperBound of the previous tier
*/
readonly lowerBound?: number;
/**
* Upper bound where this scaling tier applies
*
* The scaling tier applies if the difference between the metric
* value and its alarm threshold is lower than this value.
*
* @default +Infinity
*/
readonly upperBound?: number;
}