Skip to content

Commit 96eedbc

Browse files
ECS Scaling at 20% CPU usage.
Update ECS instance resources
1 parent 5c8cbc6 commit 96eedbc

5 files changed

Lines changed: 127 additions & 49 deletions

File tree

dotcom-rendering/cdk/bin/cdk.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { App } from 'aws-cdk-lib';
1+
import { App, Duration } from 'aws-cdk-lib';
22
import { InstanceClass, InstanceSize, InstanceType } from 'aws-cdk-lib/aws-ec2';
33
import type { RenderingCDKStackProps } from '../lib/renderingStack';
44
import { RenderingCDKStack } from '../lib/renderingStack';
@@ -111,7 +111,20 @@ export const TagPageRenderingPropsCODE: RenderingCDKStackProps = {
111111
domainName: 'tag-page-rendering.code.dev-guardianapis.com',
112112
scaling: { minimumInstances: 1, maximumInstances: 3 },
113113
instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.SMALL),
114-
imageIdentifier: getImageIdentifier(),
114+
ecsProps: {
115+
imageIdentifier: getImageIdentifier(),
116+
taskCpu: 1024,
117+
taskMemoryLimitMiB: 2048,
118+
scaling: {
119+
minimumTasks: 1,
120+
maximumTasks: 9,
121+
cpuScaling: {
122+
targetValue: 20,
123+
scaleInCooldown: Duration.seconds(60),
124+
scaleOutCooldown: Duration.seconds(60),
125+
},
126+
},
127+
},
115128
};
116129

117130
new RenderingCDKStack(
@@ -150,7 +163,20 @@ export const TagPageRenderingPropsPROD: RenderingCDKStackProps = {
150163
},
151164
},
152165
instanceType: InstanceType.of(InstanceClass.C8G, InstanceSize.MEDIUM),
153-
imageIdentifier: getImageIdentifier(),
166+
ecsProps: {
167+
imageIdentifier: getImageIdentifier(),
168+
taskCpu: 2048,
169+
taskMemoryLimitMiB: 4096,
170+
scaling: {
171+
minimumTasks: 9,
172+
maximumTasks: 90,
173+
cpuScaling: {
174+
targetValue: 20,
175+
scaleInCooldown: Duration.seconds(60),
176+
scaleOutCooldown: Duration.seconds(60),
177+
},
178+
},
179+
},
154180
};
155181

156182
new RenderingCDKStack(

dotcom-rendering/cdk/lib/__snapshots__/renderingStack.test.ts.snap

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2080,7 +2080,7 @@ exports[`The RenderingCDKStack matches the snapshot for Tag Page Rendering CODE
20802080
"EcsTaskDefinitionTaskRoleB7B6D8DD",
20812081
],
20822082
"Properties": {
2083-
"MaxCapacity": 2,
2083+
"MaxCapacity": 9,
20842084
"MinCapacity": 1,
20852085
"ResourceId": {
20862086
"Fn::Join": [
@@ -3637,6 +3637,24 @@ systemctl start tag-page-rendering",
36373637
},
36383638
"Type": "AWS::IAM::InstanceProfile",
36393639
},
3640+
"tagpagerenderingCpuScaling1742C101": {
3641+
"Properties": {
3642+
"PolicyName": "TagPageRenderingCODEtagpagerenderingCpuScalingAFEBC723",
3643+
"PolicyType": "TargetTrackingScaling",
3644+
"ScalingTargetId": {
3645+
"Ref": "EcsServiceTaskCountTarget02FCCE22",
3646+
},
3647+
"TargetTrackingScalingPolicyConfiguration": {
3648+
"PredefinedMetricSpecification": {
3649+
"PredefinedMetricType": "ECSServiceAverageCPUUtilizationHighResolution",
3650+
},
3651+
"ScaleInCooldown": 60,
3652+
"ScaleOutCooldown": 60,
3653+
"TargetValue": 20,
3654+
},
3655+
},
3656+
"Type": "AWS::ApplicationAutoScaling::ScalingPolicy",
3657+
},
36403658
"tagpagerenderingEcsClusterE7696595": {
36413659
"Properties": {
36423660
"ClusterSettings": [
@@ -4222,8 +4240,8 @@ exports[`The RenderingCDKStack matches the snapshot for Tag Page Rendering PROD
42224240
"EcsTaskDefinitionTaskRoleB7B6D8DD",
42234241
],
42244242
"Properties": {
4225-
"MaxCapacity": 2,
4226-
"MinCapacity": 1,
4243+
"MaxCapacity": 90,
4244+
"MinCapacity": 9,
42274245
"ResourceId": {
42284246
"Fn::Join": [
42294247
"",
@@ -4442,15 +4460,15 @@ exports[`The RenderingCDKStack matches the snapshot for Tag Page Rendering PROD
44424460
"ReadonlyRootFilesystem": true,
44434461
},
44444462
],
4445-
"Cpu": "1024",
4463+
"Cpu": "2048",
44464464
"ExecutionRoleArn": {
44474465
"Fn::GetAtt": [
44484466
"EcsTaskDefinitionExecutionRoleBE450C73",
44494467
"Arn",
44504468
],
44514469
},
44524470
"Family": "TagPageRenderingPRODEcsTaskDefinition12224835",
4453-
"Memory": "2048",
4471+
"Memory": "4096",
44544472
"NetworkMode": "awsvpc",
44554473
"RequiresCompatibilities": [
44564474
"FARGATE",
@@ -6202,6 +6220,24 @@ systemctl start tag-page-rendering",
62026220
},
62036221
"Type": "AWS::IAM::InstanceProfile",
62046222
},
6223+
"tagpagerenderingCpuScaling1742C101": {
6224+
"Properties": {
6225+
"PolicyName": "TagPageRenderingPRODtagpagerenderingCpuScaling4582D272",
6226+
"PolicyType": "TargetTrackingScaling",
6227+
"ScalingTargetId": {
6228+
"Ref": "EcsServiceTaskCountTarget02FCCE22",
6229+
},
6230+
"TargetTrackingScalingPolicyConfiguration": {
6231+
"PredefinedMetricSpecification": {
6232+
"PredefinedMetricType": "ECSServiceAverageCPUUtilizationHighResolution",
6233+
},
6234+
"ScaleInCooldown": 60,
6235+
"ScaleOutCooldown": 60,
6236+
"TargetValue": 20,
6237+
},
6238+
},
6239+
"Type": "AWS::ApplicationAutoScaling::ScalingPolicy",
6240+
},
62056241
"tagpagerenderingEcsClusterE7696595": {
62066242
"Properties": {
62076243
"ClusterSettings": [

dotcom-rendering/cdk/lib/renderingStack.ts

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from '@guardian/cdk/lib/constructs/core';
99
import { GuCname } from '@guardian/cdk/lib/constructs/dns/dns-records';
1010
import { GuAllowPolicy } from '@guardian/cdk/lib/constructs/iam';
11+
import type { GuLoadBalancedAppExperimentalProps } from '@guardian/cdk/lib/experimental/patterns/gu-load-balanced-app';
1112
import { GuLoadBalancedAppExperimental } from '@guardian/cdk/lib/experimental/patterns/gu-load-balanced-app';
1213
import type { GuAsgCapacity } from '@guardian/cdk/lib/types';
1314
import { aws_cloudwatch, type App as CDKApp, Duration } from 'aws-cdk-lib';
@@ -46,14 +47,32 @@ export interface RenderingCDKStackProps extends Omit<GuStackProps, 'stack'> {
4647
};
4748

4849
/**
49-
* Which image to run.
50-
* This should be the image digest (e.g. 'sha256:abc123') to ensure immutable deployments.
51-
*
52-
* @note Currently optional to control which services run in an EC2-ECS hybrid mode, or EC2-only.
53-
*
54-
* @see https://docs.docker.com/dhi/core-concepts/digests
50+
* ECS configuration including image identifier and instance sizing.
51+
* Optional to control which services run in an EC2-ECS hybrid mode, or EC2-only.
5552
*/
56-
imageIdentifier?: string;
53+
ecsProps?: {
54+
/**
55+
* Which image to run.
56+
* This should be the image digest (e.g. 'sha256:abc123') to ensure immutable deployments.
57+
*
58+
* @see https://docs.docker.com/dhi/core-concepts/digests
59+
*/
60+
imageIdentifier: string;
61+
62+
/**
63+
* vCPU units for the ECS task
64+
*/
65+
taskCpu: number;
66+
67+
/**
68+
* Memory in MB for ECS task
69+
*/
70+
taskMemoryLimitMiB: number;
71+
72+
scaling: NonNullable<
73+
GuLoadBalancedAppExperimentalProps['ecsProps']
74+
>['scaling'];
75+
};
5776
}
5877

5978
const addCPUStepScalingPolicy = (
@@ -200,14 +219,8 @@ export class RenderingCDKStack extends CDKStack {
200219
});
201220

202221
const { stack: guStack, region, account } = this;
203-
const {
204-
guApp,
205-
stage,
206-
instanceType,
207-
scaling,
208-
domainName,
209-
imageIdentifier,
210-
} = props;
222+
const { guApp, stage, instanceType, scaling, domainName, ecsProps } =
223+
props;
211224

212225
const artifactsBucket =
213226
GuDistributionBucketParameter.getInstance(this).valueAsString;
@@ -276,21 +289,17 @@ export class RenderingCDKStack extends CDKStack {
276289
}),
277290
},
278291

279-
// Provision ECS resources only when `imageIdentifier` has been provided
280-
...(imageIdentifier == null
292+
// Provision ECS resources only when `ecsProps` has been provided
293+
...(ecsProps == null
281294
? {}
282295
: {
283296
ecsProps: {
284297
repositoryName: 'guardian/dotcom-rendering',
285-
imageIdentifier,
286-
287-
// TODO tune these values
288-
memoryLimitMiB: 2048,
289-
cpu: 1024,
290-
scaling: {
291-
minimumTasks: 1,
292-
maximumTasks: 2,
293-
},
298+
imageIdentifier: ecsProps.imageIdentifier,
299+
300+
memoryLimitMiB: ecsProps.taskMemoryLimitMiB,
301+
cpu: ecsProps.taskCpu,
302+
scaling: ecsProps.scaling,
294303
},
295304

296305
// Route all traffic to EC2
@@ -303,7 +312,6 @@ export class RenderingCDKStack extends CDKStack {
303312

304313
if (app.ecsService) {
305314
const { taskDefinition } = app.ecsService;
306-
307315
const ecsEnvVars: Record<string, string> = {
308316
// Custom environment variables needed by the application
309317
NODE_ENV: 'production',

pnpm-lock.yaml

Lines changed: 21 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ blockExoticSubdeps: true
1212
catalog:
1313
'@aws-sdk/client-s3': 3.995.0
1414
'@aws-sdk/client-ssm': 3.995.0
15-
'@guardian/cdk': 64.6.0
15+
'@guardian/cdk': 64.7.0
1616
'@guardian/eslint-config': 14.0.1
1717
'@guardian/tsconfig': 1.0.1
1818
'@rollup/plugin-commonjs': 29.0.0

0 commit comments

Comments
 (0)