Skip to content

Commit

Permalink
feat(autoscaling): add getter/setter for instance termination protect…
Browse files Browse the repository at this point in the history
…ion (aws#14308)

Adds getter/setter methods for enabling and querying instance termination protection. This will be used by EC2 Capacity Provider support for ECS to ensure the flag is set correctly when managed termination protection is enabled.

This is a follow up to aws#14283.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
otterley authored and hollanddd committed Aug 26, 2021
1 parent aeb4977 commit 5a0dc55
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 22 deletions.
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-autoscaling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,8 @@ policy](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termin

However, you may wish to protect newly-launched instances from being scaled in
if they are going to run critical applications that should not be prematurely
terminated. This protection can be removed after launch.
terminated. EC2 Capacity Providers for Amazon ECS requires this attribute be
set to `true`.

```ts
new autoscaling.AutoScalingGroup(stack, 'ASG', {
Expand Down
22 changes: 20 additions & 2 deletions packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ export interface CommonAutoScalingGroupProps {
* when scaling in an Auto Scaling Group, subject to the group's termination
* policy. However, you may wish to protect newly-launched instances from
* being scaled in if they are going to run critical applications that should
* not beß prematurely terminated.
* not be prematurely terminated.
*
* This flag must be enabled if the Auto Scaling Group will be associated with
* an ECS Capacity Provider with managed termination protection.
Expand Down Expand Up @@ -918,11 +918,15 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
private readonly groupMetrics: GroupMetrics[] = [];
private readonly notifications: NotificationConfiguration[] = [];

protected newInstancesProtectedFromScaleIn?: boolean;

constructor(scope: Construct, id: string, props: AutoScalingGroupProps) {
super(scope, id, {
physicalName: props.autoScalingGroupName,
});

this.newInstancesProtectedFromScaleIn = props.newInstancesProtectedFromScaleIn;

if (props.initOptions && !props.init) {
throw new Error('Setting \'initOptions\' requires that \'init\' is also set');
}
Expand Down Expand Up @@ -1038,7 +1042,7 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
healthCheckType: props.healthCheck && props.healthCheck.type,
healthCheckGracePeriod: props.healthCheck && props.healthCheck.gracePeriod && props.healthCheck.gracePeriod.toSeconds(),
maxInstanceLifetime: this.maxInstanceLifetime ? this.maxInstanceLifetime.toSeconds() : undefined,
newInstancesProtectedFromScaleIn: props.newInstancesProtectedFromScaleIn,
newInstancesProtectedFromScaleIn: Lazy.any({ produce: () => this.newInstancesProtectedFromScaleIn }),
};

if (!hasPublic && props.associatePublicIpAddress) {
Expand Down Expand Up @@ -1144,6 +1148,20 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
});
}

/**
* Ensures newly-launched instances are protected from scale-in.
*/
public protectNewInstancesFromScaleIn() {
this.newInstancesProtectedFromScaleIn = true;
}

/**
* Returns `true` if newly-launched instances are protected from scale-in.
*/
public areNewInstancesProtectedFromScaleIn(): boolean {
return this.newInstancesProtectedFromScaleIn === true;
}

/**
* Apply CloudFormation update policies for the AutoScalingGroup
*/
Expand Down
63 changes: 44 additions & 19 deletions packages/@aws-cdk/aws-autoscaling/test/auto-scaling-group.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,50 @@ nodeunitShim({
test.deepEqual(Object.values(autoscaling.ScalingEvent).length - 1, autoscaling.ScalingEvents.ALL._types.length);
test.done();
},

'Can protect new instances from scale-in via constructor property'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = mockVpc(stack);

// WHEN
const asg = new autoscaling.AutoScalingGroup(stack, 'MyASG', {
instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage(),
vpc,
newInstancesProtectedFromScaleIn: true,
});

// THEN
test.strictEqual(asg.areNewInstancesProtectedFromScaleIn(), true);
expect(stack).to(haveResourceLike('AWS::AutoScaling::AutoScalingGroup', {
NewInstancesProtectedFromScaleIn: true,
}));

test.done();
},

'Can protect new instances from scale-in via setter'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = mockVpc(stack);

// WHEN
const asg = new autoscaling.AutoScalingGroup(stack, 'MyASG', {
instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage(),
vpc,
});
asg.protectNewInstancesFromScaleIn();

// THEN
test.strictEqual(asg.areNewInstancesProtectedFromScaleIn(), true);
expect(stack).to(haveResourceLike('AWS::AutoScaling::AutoScalingGroup', {
NewInstancesProtectedFromScaleIn: true,
}));

test.done();
},
});

function mockVpc(stack: cdk.Stack) {
Expand Down Expand Up @@ -1345,25 +1389,6 @@ test('Can set autoScalingGroupName', () => {
}));
});

test('Can protect new instances from scale-in', () => {
// GIVEN
const stack = new cdk.Stack();
const vpc = mockVpc(stack);

// WHEN
new autoscaling.AutoScalingGroup(stack, 'MyASG', {
instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage(),
vpc,
newInstancesProtectedFromScaleIn: true,
});

// THEN
expect(stack).to(haveResourceLike('AWS::AutoScaling::AutoScalingGroup', {
NewInstancesProtectedFromScaleIn: true,
}));
});

test('can use Vpc imported from unparseable list tokens', () => {
// GIVEN
const stack = new cdk.Stack();
Expand Down

0 comments on commit 5a0dc55

Please sign in to comment.