From 9347a7161b1150814b5c641c8568c278f68fa781 Mon Sep 17 00:00:00 2001 From: Jimmy Gaussen Date: Thu, 25 Jul 2019 14:26:03 +0200 Subject: [PATCH] feat(autoscaling): health check configuration (#3390) Implements missing Auto Scaling Group properties [HealthCheckType](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html#cfn-as-group-healthchecktype) and [HealthCheckGracePeriod](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html#cfn-as-group-healthcheckgraceperiod) They are grouped in a `healthCheck` object property. The constructor checks that the following requirement is fulfilled: > If you are adding an ELB health check, you must specify this property. Fixes #3381 --- .../aws-autoscaling/lib/auto-scaling-group.ts | 66 ++++++++++++++++++- .../test/test.auto-scaling-group.ts | 43 ++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts index 6594dc67249e5..2782bb1905d89 100644 --- a/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts @@ -156,6 +156,13 @@ export interface CommonAutoScalingGroupProps { * @default none */ readonly spotPrice?: string; + + /** + * Configuration for health checks + * + * @default - HealthCheck.ec2 with no grace period + */ + readonly healthCheck?: HealthCheck; } /** @@ -444,7 +451,9 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements ], } ], - vpcZoneIdentifier: subnetIds + vpcZoneIdentifier: subnetIds, + healthCheckType: props.healthCheck && props.healthCheck.type, + healthCheckGracePeriod: props.healthCheck && props.healthCheck.gracePeriod && props.healthCheck.gracePeriod.toSeconds(), }; if (!hasPublic && props.associatePublicIpAddress) { @@ -673,6 +682,61 @@ export enum ScalingProcess { ADD_TO_LOAD_BALANCER = 'AddToLoadBalancer' } +/** + * EC2 Heath check options + */ +export interface Ec2HealthCheckOptions { + /** + * Specified the time Auto Scaling waits before checking the health status of an EC2 instance that has come into service + * + * @default Duration.seconds(0) + */ + readonly grace?: Duration; +} + +/** + * ELB Heath check options + */ +export interface ElbHealthCheckOptions { + /** + * Specified the time Auto Scaling waits before checking the health status of an EC2 instance that has come into service + * + * This option is required for ELB health checks. + */ + readonly grace: Duration; +} + +/** + * Health check settings + */ +export class HealthCheck { + /** + * Use EC2 for health checks + * + * @param options EC2 health check options + */ + public static ec2(options: Ec2HealthCheckOptions = {}): HealthCheck { + return new HealthCheck(HealthCheckType.EC2, options.grace); + } + + /** + * Use ELB for health checks. + * It considers the instance unhealthy if it fails either the EC2 status checks or the load balancer health checks. + * + * @param options ELB health check options + */ + public static elb(options: ElbHealthCheckOptions): HealthCheck { + return new HealthCheck(HealthCheckType.ELB, options.grace); + } + + private constructor(public readonly type: string, public readonly gracePeriod?: Duration) { } +} + +enum HealthCheckType { + EC2 = 'EC2', + ELB = 'ELB', +} + /** * Render the rolling update configuration into the appropriate object */ diff --git a/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts b/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts index 89a456e40fe51..722c368ccc2a4 100644 --- a/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts +++ b/packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts @@ -397,6 +397,49 @@ export = { test.done(); }, + 'can configure EC2 health check'(test: Test) { + // GIVEN + const stack = new cdk.Stack(undefined, 'MyStack', { env: { region: 'us-east-1', account: '1234' } }); + const vpc = mockVpc(stack); + + // WHEN + new autoscaling.AutoScalingGroup(stack, 'MyFleet', { + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + machineImage: new ec2.AmazonLinuxImage(), + vpc, + healthCheck: autoscaling.HealthCheck.ec2() + }); + + // THEN + expect(stack).to(haveResourceLike("AWS::AutoScaling::AutoScalingGroup", { + HealthCheckType: 'EC2', + })); + + test.done(); + }, + + 'can configure EBS health check'(test: Test) { + // GIVEN + const stack = new cdk.Stack(undefined, 'MyStack', { env: { region: 'us-east-1', account: '1234' } }); + const vpc = mockVpc(stack); + + // WHEN + new autoscaling.AutoScalingGroup(stack, 'MyFleet', { + instanceType: ec2.InstanceType.of(ec2.InstanceClass.M4, ec2.InstanceSize.MICRO), + machineImage: new ec2.AmazonLinuxImage(), + vpc, + healthCheck: autoscaling.HealthCheck.elb({grace: cdk.Duration.minutes(15)}) + }); + + // THEN + expect(stack).to(haveResourceLike("AWS::AutoScaling::AutoScalingGroup", { + HealthCheckType: 'ELB', + HealthCheckGracePeriod: 900 + })); + + test.done(); + }, + 'can add Security Group to Fleet'(test: Test) { // GIVEN const stack = new cdk.Stack(undefined, 'MyStack', { env: { region: 'us-east-1', account: '1234' } });