Skip to content
This repository has been archived by the owner on Jun 13, 2024. It is now read-only.

Commit

Permalink
feat(autoscaling): support max instance lifetime
Browse files Browse the repository at this point in the history
- [x] implementation
- [x] integ test
- [x] unit test
- [x] README


### Commit Message

feat(autoscaling): support maxInstanceLifetime property

Thie PR allow `autoscaling.AutoScalingGroup` to specify its max instance lifetime property.

Closes aws#7758 
### End Commit Message

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
pahud authored May 20, 2020
1 parent 9680f0e commit d126c46
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 0 deletions.
8 changes: 8 additions & 0 deletions packages/@aws-cdk/aws-autoscaling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,14 @@ autoScalingGroup.scaleOnSchedule('AllowDownscalingAtNight', {
See the documentation of the `@aws-cdk/aws-ec2` package for more information
about allowing connections between resources backed by instances.

### Max Instance Lifetime

To enable the max instance lifetime support, specify `maxInstanceLifetime` property
for the `AutoscalingGroup` resource. The value must be between 7 and 365 days(inclusive).
To clear a previously set value, just leave this property undefinied.



### Future work

- [ ] CloudWatch Events (impossible to add currently as the AutoScalingGroup ARN is
Expand Down
26 changes: 26 additions & 0 deletions packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,20 @@ export interface CommonAutoScalingGroupProps {
* @default - Uses the block device mapping of the AMI
*/
readonly blockDevices?: BlockDevice[];

/**
* The maximum amount of time that an instance can be in service. The maximum duration applies
* to all current and future instances in the group. As an instance approaches its maximum duration,
* it is terminated and replaced, and cannot be used again.
*
* You must specify a value of at least 604,800 seconds (7 days). To clear a previously set value,
* simply leave this property undefinied.
*
* @see https://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-max-instance-lifetime.html
*
* @default none
*/
readonly maxInstanceLifetime?: Duration;
}

/**
Expand Down Expand Up @@ -411,6 +425,11 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
*/
public readonly spotPrice?: string;

/**
* The maximum amount of time that an instance can be in service.
*/
public readonly maxInstanceLifetime?: Duration;

private readonly autoScalingGroup: CfnAutoScalingGroup;
private readonly securityGroup: ec2.ISecurityGroup;
private readonly securityGroups: ec2.ISecurityGroup[] = [];
Expand Down Expand Up @@ -492,6 +511,12 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
this.node.addWarning('desiredCapacity has been configured. Be aware this will reset the size of your AutoScalingGroup on every deployment. See https://github.com/aws/aws-cdk/issues/5215');
}

this.maxInstanceLifetime = props.maxInstanceLifetime;
if (this.maxInstanceLifetime &&
(this.maxInstanceLifetime.toSeconds() < 604800 || this.maxInstanceLifetime.toSeconds() > 31536000)) {
throw new Error('maxInstanceLifetime must be between 7 and 365 days (inclusive)');
}

const { subnetIds, hasPublic } = props.vpc.selectSubnets(props.vpcSubnets);
const asgProps: CfnAutoScalingGroupProps = {
cooldown: props.cooldown !== undefined ? props.cooldown.toSeconds().toString() : undefined,
Expand All @@ -515,6 +540,7 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
vpcZoneIdentifier: subnetIds,
healthCheckType: props.healthCheck && props.healthCheck.type,
healthCheckGracePeriod: props.healthCheck && props.healthCheck.gracePeriod && props.healthCheck.gracePeriod.toSeconds(),
maxInstanceLifetime: this.maxInstanceLifetime ? this.maxInstanceLifetime.toSeconds() : undefined,
};

if (!hasPublic && props.associatePublicIpAddress) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@
"LaunchConfigurationName": {
"Ref": "FleetLaunchConfig59F79D36"
},
"MaxInstanceLifetime": 604800,
"Tags": [
{
"Key": "Name",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ new autoscaling.AutoScalingGroup(stack, 'Fleet', {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }),
maxInstanceLifetime: cdk.Duration.days(7),
});

app.synth();
55 changes: 55 additions & 0 deletions packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,61 @@ export = {
test.done();
},

'can configure maxInstanceLifetime'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = mockVpc(stack);
new autoscaling.AutoScalingGroup(stack, 'MyStack', {
instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage(),
vpc,
maxInstanceLifetime: cdk.Duration.days(7),
});

// THEN
expect(stack).to(haveResource('AWS::AutoScaling::AutoScalingGroup', {
'MaxInstanceLifetime': 604800,
}));

test.done();
},

'throws if maxInstanceLifetime < 7 days'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = mockVpc(stack);

// THEN
test.throws(() => {
new autoscaling.AutoScalingGroup(stack, 'MyStack', {
instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage(),
vpc,
maxInstanceLifetime: cdk.Duration.days(6),
});
}, /maxInstanceLifetime must be between 7 and 365 days \(inclusive\)/);

test.done();
},

'throws if maxInstanceLifetime > 365 days'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = mockVpc(stack);

// THEN
test.throws(() => {
new autoscaling.AutoScalingGroup(stack, 'MyStack', {
instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage(),
vpc,
maxInstanceLifetime: cdk.Duration.days(366),
});
}, /maxInstanceLifetime must be between 7 and 365 days \(inclusive\)/);

test.done();
},

'throws if ephemeral volumeIndex < 0'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
Expand Down

0 comments on commit d126c46

Please sign in to comment.