Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(autoscaling): support warm pools #19214

Merged
merged 6 commits into from Mar 23, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions packages/@aws-cdk/aws-autoscaling/README.md
Expand Up @@ -488,6 +488,27 @@ const aspect = new autoscaling.AutoScalingGroupRequireImdsv2Aspect();
Aspects.of(this).add(aspect);
```

## Warm Pool

Auto Scaling offers [a warm pool](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-warm-pools.html) which gives an ability to decrease latency for applications that have exceptionally long boot times. You can create a warm pool with default parameters as below:

```ts
declare const autoScalingGroup: autoscaling.AutoScalingGroup;

autoScalingGroup.addWarmPool();
```

You can also customize a warm pool by configuring parameters:

```ts
declare const autoScalingGroup: autoscaling.AutoScalingGroup;

autoScalingGroup.addWarmPool({
minSize: 1,
reuseOnScaleIn: true,
});
```

## Future work

* [ ] CloudWatch Events (impossible to add currently as the AutoScalingGroup ARN is
Expand Down
16 changes: 16 additions & 0 deletions packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts
Expand Up @@ -23,6 +23,7 @@ import { BasicStepScalingPolicyProps, StepScalingPolicy } from './step-scaling-p
import { BaseTargetTrackingProps, PredefinedMetric, TargetTrackingScalingPolicy } from './target-tracking-scaling-policy';
import { TerminationPolicy } from './termination-policy';
import { BlockDevice, BlockDeviceVolume, EbsDeviceVolumeType } from './volume';
import { WarmPool, WarmPoolOptions } from './warm-pool';

/**
* Name tag constant
Expand Down Expand Up @@ -744,6 +745,16 @@ abstract class AutoScalingGroupBase extends Resource implements IAutoScalingGrou
});
}

/**
* Add a pool of pre-initialized EC2 instances that sits alongside an Auto Scaling group
*/
public addWarmPool(options?: WarmPoolOptions): WarmPool {
return new WarmPool(this, 'WarmPool', {
autoScalingGroup: this,
...options,
});
}

/**
* Scale out or in based on time
*/
Expand Down Expand Up @@ -1630,6 +1641,11 @@ export interface IAutoScalingGroup extends IResource, iam.IGrantable {
*/
addLifecycleHook(id: string, props: BasicLifecycleHookProps): LifecycleHook;

/**
* Add a pool of pre-initialized EC2 instances that sits alongside an Auto Scaling group
*/
addWarmPool(options?: WarmPoolOptions): WarmPool;

/**
* Scale out or in based on time
*/
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-autoscaling/lib/index.ts
Expand Up @@ -9,6 +9,7 @@ export * from './step-scaling-policy';
export * from './target-tracking-scaling-policy';
export * from './termination-policy';
export * from './volume';
export * from './warm-pool';

// AWS::AutoScaling CloudFormation Resources:
export * from './autoscaling.generated';
104 changes: 104 additions & 0 deletions packages/@aws-cdk/aws-autoscaling/lib/warm-pool.ts
@@ -0,0 +1,104 @@
import { Lazy, Names, Resource } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { IAutoScalingGroup } from './auto-scaling-group';
import { CfnWarmPool } from './autoscaling.generated';

/**
* Options for a warm pool
*/
export interface WarmPoolOptions {
/**
* Indicates whether instances in the Auto Scaling group can be returned to the warm pool on scale in.
*
* If the value is not specified, instances in the Auto Scaling group will be terminated
* when the group scales in.
*
* @default - false
kaizencc marked this conversation as resolved.
Show resolved Hide resolved
*/
readonly reuseOnScaleIn?: boolean;

/**
* The maximum number of instances that are allowed to be in the warm pool
* or in any state except Terminated for the Auto Scaling group.
*
* If the value is not specified, Amazon EC2 Auto Scaling launches and maintains
* the difference between the group's maximum capacity and its desired capacity.
*
* @default - max size of the Auto Scaling group
*/
readonly maxGroupPreparedCapacity?: number;
/**
* The minimum number of instances to maintain in the warm pool.
*
* @default - 0
kaizencc marked this conversation as resolved.
Show resolved Hide resolved
*/
readonly minSize?: number;
/**
* The instance state to transition to after the lifecycle actions are complete.
*
* @default - STOPPED
kaizencc marked this conversation as resolved.
Show resolved Hide resolved
*/
readonly poolState?: PoolState;
}

/**
* Properties for a warm pool
*/
export interface WarmPoolProps extends WarmPoolOptions {
/**
* The Auto Scaling group to add the warm pool to.
*/
readonly autoScalingGroup: IAutoScalingGroup;
}

/**
* Define a warm pool
*/
export class WarmPool extends Resource {
constructor(scope: Construct, id: string, props: WarmPoolProps) {
super(scope, id, {
physicalName: Lazy.string({ produce: () => Names.uniqueId(this) }),
});

if (props.maxGroupPreparedCapacity && props.maxGroupPreparedCapacity < -1) {
throw new Error('\'maxGroupPreparedCapacity\' parameter should be greater than or equal to -1');
}

if (props.minSize && props.minSize < 0) {
throw new Error('\'minSize\' parameter should be greater than or equal to 0');
}

new CfnWarmPool(this, 'Resource', {
autoScalingGroupName: props.autoScalingGroup.autoScalingGroupName,
instanceReusePolicy: props.reuseOnScaleIn !== undefined ? {
reuseOnScaleIn: props.reuseOnScaleIn,
} : undefined,
maxGroupPreparedCapacity: props.maxGroupPreparedCapacity,
minSize: props.minSize && props.minSize,
poolState: props.poolState && props.poolState,
jungseoklee marked this conversation as resolved.
Show resolved Hide resolved
kaizencc marked this conversation as resolved.
Show resolved Hide resolved
});
}
}

/**
* The instance state in the warm pool
*/
export enum PoolState {
/**
* Hibernated
*
* To use this state, prerequisites must be in place.
* @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/hibernating-prerequisites.html
*/
HIBERNATED = 'Hibernated',

/**
* Running
*/
RUNNING = 'Running',

/**
* Stopped
*/
STOPPED = 'Stopped',
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-autoscaling/package.json
Expand Up @@ -122,6 +122,7 @@
"export:@aws-cdk/aws-autoscaling.IAutoScalingGroup",
"props-physical-name:@aws-cdk/aws-autoscaling.AutoScalingGroupProps",
"props-physical-name:@aws-cdk/aws-autoscaling.ScheduledActionProps",
"props-physical-name:@aws-cdk/aws-autoscaling.WarmPoolProps",
kaizencc marked this conversation as resolved.
Show resolved Hide resolved
"props-default-doc:@aws-cdk/aws-autoscaling.EbsDeviceOptionsBase.iops",
"docs-public-apis:@aws-cdk/aws-autoscaling.ScalingProcess.ADD_TO_LOAD_BALANCER",
"docs-public-apis:@aws-cdk/aws-autoscaling.ScalingProcess.SCHEDULED_ACTIONS",
Expand Down