From 5d4d24c0cf7927f5883393ed768110aa951b352f Mon Sep 17 00:00:00 2001 From: Krishan Thisera Date: Wed, 1 Nov 2023 14:49:21 +1030 Subject: [PATCH] DO-1560: make the scaling options configurable --- packages/prerender-fargate/index.ts | 6 +- .../lib/prerender-fargate-options.ts | 58 +++++++++++++++++++ .../lib/prerender-fargate.ts | 27 +++++++-- 3 files changed, 85 insertions(+), 6 deletions(-) diff --git a/packages/prerender-fargate/index.ts b/packages/prerender-fargate/index.ts index e00f084e..ed7b803c 100644 --- a/packages/prerender-fargate/index.ts +++ b/packages/prerender-fargate/index.ts @@ -1,9 +1,13 @@ import { PrerenderFargate } from "./lib/prerender-fargate"; -import { PrerenderFargateOptions } from "./lib/prerender-fargate-options"; +import { + PrerenderFargateOptions, + PrerenderFargateScalingOptions, +} from "./lib/prerender-fargate-options"; import { PrerenderTokenUrlAssociationOptions } from "./lib/recaching/prerender-tokens"; export { PrerenderFargate, PrerenderFargateOptions, + PrerenderFargateScalingOptions, PrerenderTokenUrlAssociationOptions, }; diff --git a/packages/prerender-fargate/lib/prerender-fargate-options.ts b/packages/prerender-fargate/lib/prerender-fargate-options.ts index a90a320c..95d1d22b 100644 --- a/packages/prerender-fargate/lib/prerender-fargate-options.ts +++ b/packages/prerender-fargate/lib/prerender-fargate-options.ts @@ -1,4 +1,5 @@ import { PrerenderTokenUrlAssociationOptions } from "./recaching/prerender-tokens"; +import * as ec2 from "aws-cdk-lib/aws-ec2"; /** * Options for configuring the Prerender Fargate construct. @@ -35,6 +36,10 @@ export interface PrerenderFargateOptions { * The ARN of the SSL certificate to use for HTTPS connections. */ certificateArn: string; + /** + * The minimum number of Fargate instances to run. + */ + minInstanceCount?: number; /** * The desired number of Fargate instances to run. */ @@ -78,4 +83,57 @@ export interface PrerenderFargateOptions { * ``` */ tokenUrlAssociation?: PrerenderTokenUrlAssociationOptions; + /** + * Prerender Fargate Scaling option + * This allows to alter the scaling behavior. The default configuration should be sufficient + * for most of the cases. + */ + prerenderFargateScalingOptions?: PrerenderFargateScalingOptions; +} + +/** + * Prerender Fargate Scaling option + */ +export interface PrerenderFargateScalingOptions { + /** + * Fargate service health check grace period. + * The minimum number of tasks, specified as a percentage of + * the Amazon ECS service's DesiredCount value, that must + * continue to run and remain healthy during a deployment. + * @default - 20 seconds + */ + healthCheckGracePeriod?: number; + /** + * Fargate service minimum healthy percent. + * @default - 0 + */ + minHealthyPercent?: number; + /** + * Fargate service maximum healthy percent. + * This limits the scheduler from starting a replacement task first, + * the scheduler will stop an unhealthy task one at a time at random to + * free up capacity, and then start a replacement task + * @default - 200 + */ + maxHealthyPercent?: number; + /** + * Health check interval in seconds. + * @default - 50 + */ + healthCheckInterval?: number; + /** + * Scale in cooldown in seconds. + * @default - 60 + */ + scaleInCooldown?: number; + /** + * Scale out cooldown in seconds. + * @default - 60 + */ + scaleOutCooldown?: number; + /** + * The number of consecutive health check failures required before considering a task unhealthy. + * @default - 5 + */ + unhealthyThresholdCount?: number; } diff --git a/packages/prerender-fargate/lib/prerender-fargate.ts b/packages/prerender-fargate/lib/prerender-fargate.ts index 2868112e..2988fc51 100644 --- a/packages/prerender-fargate/lib/prerender-fargate.ts +++ b/packages/prerender-fargate/lib/prerender-fargate.ts @@ -98,6 +98,8 @@ export class PrerenderFargate extends Construct { bucketName, domainName, prerenderName, + minInstanceCount, + prerenderFargateScalingOptions, } = props; // Create bucket for prerender storage @@ -160,7 +162,6 @@ export class PrerenderFargate extends Construct { TOKEN_LIST: tokenList.toString(), }, }, - healthCheckGracePeriod: Duration.seconds(20), publicLoadBalancer: true, assignPublicIp: true, listenerPort: 443, @@ -174,6 +175,14 @@ export class PrerenderFargate extends Construct { "cert", certificateArn ), + // Scaling configuration + healthCheckGracePeriod: Duration.seconds( + prerenderFargateScalingOptions?.healthCheckGracePeriod || 20 + ), + minHealthyPercent: + prerenderFargateScalingOptions?.minHealthyPercent || 50, + maxHealthyPercent: + prerenderFargateScalingOptions?.maxHealthyPercent || 200, } ); @@ -184,19 +193,27 @@ export class PrerenderFargate extends Construct { // It should be considered healthy when receiving a 401 response fargateService.targetGroup.configureHealthCheck({ path: "/health", - interval: Duration.seconds(120), - unhealthyThresholdCount: 5, + interval: Duration.seconds( + prerenderFargateScalingOptions?.healthCheckInterval || 120 + ), + unhealthyThresholdCount: + prerenderFargateScalingOptions?.unhealthyThresholdCount || 5, healthyHttpCodes: "401", }); // Setup AutoScaling policy const scaling = fargateService.service.autoScaleTaskCount({ maxCapacity: maxInstanceCount || 2, + minCapacity: minInstanceCount || 1, }); scaling.scaleOnCpuUtilization(`${prerenderName}-scaling`, { targetUtilizationPercent: 50, - scaleInCooldown: Duration.seconds(60), - scaleOutCooldown: Duration.seconds(60), + scaleInCooldown: Duration.seconds( + prerenderFargateScalingOptions?.scaleInCooldown || 60 + ), + scaleOutCooldown: Duration.seconds( + prerenderFargateScalingOptions?.scaleOutCooldown || 60 + ), }); /**