Skip to content

Commit 9e6f977

Browse files
authored
feat(aws-autoscaling): Add support for termination policies (#17936)
This PR adds support for [termination policies](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html#cfn-as-group-termpolicy) to the `AutoScalingGroup` resource. `aws autoscaling describe-termination-policy-types --region us-east-2` reports the existence of a `Lambda` termination type, but that isn't documented in the CloudFormation docs, so I opted to omit it. Closes #15654.
1 parent dee732d commit 9e6f977

File tree

5 files changed

+107
-1
lines changed

5 files changed

+107
-1
lines changed

packages/@aws-cdk/aws-autoscaling/README.md

+26
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,32 @@ new autoscaling.AutoScalingGroup(this, 'ASG', {
400400
});
401401
```
402402

403+
## Termination policies
404+
405+
Auto Scaling uses [termination policies](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html)
406+
to determine which instances it terminates first during scale-in events. You
407+
can specify one or more termination policies with the `terminationPolicies`
408+
property:
409+
410+
```ts
411+
declare const vpc: ec2.Vpc;
412+
declare const instanceType: ec2.InstanceType;
413+
declare const machineImage: ec2.IMachineImage;
414+
415+
new autoscaling.AutoScalingGroup(this, 'ASG', {
416+
vpc,
417+
instanceType,
418+
machineImage,
419+
420+
// ...
421+
422+
terminationPolicies: [
423+
autoscaling.TerminationPolicy.OLDEST_INSTANCE,
424+
autoscaling.TerminationPolicy.DEFAULT,
425+
],
426+
});
427+
```
428+
403429
## Protecting new instances from being terminated on scale-in
404430

405431
By default, Auto Scaling can terminate an instance at any time after launch when

packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts

+12
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { BasicLifecycleHookProps, LifecycleHook } from './lifecycle-hook';
2121
import { BasicScheduledActionProps, ScheduledAction } from './scheduled-action';
2222
import { BasicStepScalingPolicyProps, StepScalingPolicy } from './step-scaling-policy';
2323
import { BaseTargetTrackingProps, PredefinedMetric, TargetTrackingScalingPolicy } from './target-tracking-scaling-policy';
24+
import { TerminationPolicy } from './termination-policy';
2425
import { BlockDevice, BlockDeviceVolume, EbsDeviceVolumeType } from './volume';
2526

2627
/**
@@ -314,6 +315,16 @@ export interface CommonAutoScalingGroupProps {
314315
* @default - Auto generated by CloudFormation
315316
*/
316317
readonly autoScalingGroupName?: string;
318+
319+
/**
320+
* A policy or a list of policies that are used to select the instances to
321+
* terminate. The policies are executed in the order that you list them.
322+
*
323+
* @see https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html
324+
*
325+
* @default - `TerminationPolicy.DEFAULT`
326+
*/
327+
readonly terminationPolicies?: TerminationPolicy[];
317328
}
318329

319330
/**
@@ -1052,6 +1063,7 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
10521063
healthCheckGracePeriod: props.healthCheck && props.healthCheck.gracePeriod && props.healthCheck.gracePeriod.toSeconds(),
10531064
maxInstanceLifetime: this.maxInstanceLifetime ? this.maxInstanceLifetime.toSeconds() : undefined,
10541065
newInstancesProtectedFromScaleIn: Lazy.any({ produce: () => this.newInstancesProtectedFromScaleIn }),
1066+
terminationPolicies: props.terminationPolicies,
10551067
};
10561068

10571069
if (!hasPublic && props.associatePublicIpAddress) {

packages/@aws-cdk/aws-autoscaling/lib/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ export * from './scheduled-action';
77
export * from './step-scaling-action';
88
export * from './step-scaling-policy';
99
export * from './target-tracking-scaling-policy';
10+
export * from './termination-policy';
1011
export * from './volume';
1112

1213
// AWS::AutoScaling CloudFormation Resources:
13-
export * from './autoscaling.generated';
14+
export * from './autoscaling.generated';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Specifies the termination criteria to apply before Amazon EC2 Auto Scaling
3+
* chooses an instance for termination.
4+
*/
5+
export enum TerminationPolicy {
6+
/**
7+
* Terminate instances in the Auto Scaling group to align the remaining
8+
* instances to the allocation strategy for the type of instance that is
9+
* terminating (either a Spot Instance or an On-Demand Instance).
10+
*/
11+
ALLOCATION_STRATEGY = 'AllocationStrategy',
12+
13+
/**
14+
* Terminate instances that are closest to the next billing hour.
15+
*/
16+
CLOSEST_TO_NEXT_INSTANCE_HOUR = 'ClosestToNextInstanceHour',
17+
18+
/**
19+
* Terminate instances according to the default termination policy.
20+
*/
21+
DEFAULT = 'Default',
22+
23+
/**
24+
* Terminate the newest instance in the group.
25+
*/
26+
NEWEST_INSTANCE = 'NewestInstance',
27+
28+
/**
29+
* Terminate the oldest instance in the group.
30+
*/
31+
OLDEST_INSTANCE = 'OldestInstance',
32+
33+
/**
34+
* Terminate instances that have the oldest launch configuration.
35+
*/
36+
OLDEST_LAUNCH_CONFIGURATION = 'OldestLaunchConfiguration',
37+
38+
/**
39+
* Terminate instances that have the oldest launch template.
40+
*/
41+
OLDEST_LAUNCH_TEMPLATE = 'OldestLaunchTemplate',
42+
}

packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts

+25
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,31 @@ describe('auto scaling group', () => {
13821382
},
13831383
});
13841384
});
1385+
1386+
test('supports termination policies', () => {
1387+
// GIVEN
1388+
const stack = new cdk.Stack();
1389+
const vpc = mockVpc(stack);
1390+
1391+
// WHEN
1392+
new autoscaling.AutoScalingGroup(stack, 'MyASG', {
1393+
vpc,
1394+
instanceType: new ec2.InstanceType('t2.micro'),
1395+
machineImage: ec2.MachineImage.latestAmazonLinux(),
1396+
terminationPolicies: [
1397+
autoscaling.TerminationPolicy.OLDEST_INSTANCE,
1398+
autoscaling.TerminationPolicy.DEFAULT,
1399+
],
1400+
});
1401+
1402+
// THEN
1403+
expect(stack).toHaveResource('AWS::AutoScaling::AutoScalingGroup', {
1404+
TerminationPolicies: [
1405+
'OldestInstance',
1406+
'Default',
1407+
],
1408+
});
1409+
});
13851410
});
13861411

13871412
function mockVpc(stack: cdk.Stack) {

0 commit comments

Comments
 (0)