Skip to content

Commit

Permalink
Merge pull request #2385 from guardian/add-defaultInstanceWarmup-opti…
Browse files Browse the repository at this point in the history
…on-gu-ec2-app-pattern

Adds defaultInstanceWarmup option to GuEC2App pattern
  • Loading branch information
SHession authored Jul 24, 2024
2 parents e02d8d8 + 8700b29 commit c4b0862
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/nice-roses-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@guardian/cdk": minor
---

feat(asg): Allow setting the defaultInstanceWarmup option on auto scaling groups provisioned by our EC2 pattern
6 changes: 5 additions & 1 deletion src/constructs/autoscaling/asg.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Duration } from "aws-cdk-lib";
import { Tags, Token } from "aws-cdk-lib";
import { AutoScalingGroup, GroupMetric, GroupMetrics } from "aws-cdk-lib/aws-autoscaling";
import type { AutoScalingGroupProps, CfnAutoScalingGroup } from "aws-cdk-lib/aws-autoscaling";
Expand Down Expand Up @@ -51,6 +52,7 @@ export interface GuAutoScalingGroupProps
withoutImdsv2?: boolean;
httpPutResponseHopLimit?: number;
enabledDetailedInstanceMonitoring?: boolean;
defaultInstanceWarmup?: Duration;
}

/**
Expand Down Expand Up @@ -97,6 +99,7 @@ export class GuAutoScalingGroup extends GuAppAwareConstruct(AutoScalingGroup) {
httpPutResponseHopLimit,
updatePolicy,
enabledDetailedInstanceMonitoring,
defaultInstanceWarmup,
} = props;

// Ensure min and max are defined in the same way. Throwing an `Error` when necessary. For example when min is defined via a Mapping, but max is not.
Expand Down Expand Up @@ -137,7 +140,7 @@ export class GuAutoScalingGroup extends GuAppAwareConstruct(AutoScalingGroup) {
launchTemplate.connections.addSecurityGroup(sg),
);

const asgProps = {
const asgProps: AutoScalingGroupProps = {
...props,
launchTemplate,
maxCapacity: maximumInstances ?? minimumInstances * 2,
Expand All @@ -150,6 +153,7 @@ export class GuAutoScalingGroup extends GuAppAwareConstruct(AutoScalingGroup) {
instanceType: undefined,
role: undefined,
userData: undefined,
defaultInstanceWarmup,
};

super(scope, id, asgProps);
Expand Down
26 changes: 26 additions & 0 deletions src/patterns/ec2-app/base.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Duration } from "aws-cdk-lib";
import { Match, Template } from "aws-cdk-lib/assertions";
import { BlockDeviceVolume, EbsDeviceVolumeType, UpdatePolicy } from "aws-cdk-lib/aws-autoscaling";
import { InstanceClass, InstanceSize, InstanceType, Peer, Port, UserData, Vpc } from "aws-cdk-lib/aws-ec2";
Expand Down Expand Up @@ -1151,4 +1152,29 @@ UserData from accessed construct`);
},
});
});

it("set defaultInstanceWarmup on the ASG when set", function () {
const stack = simpleGuStackForTesting();
new GuEc2App(stack, {
applicationPort: 3000,
app: "test-gu-ec2-app",
access: { scope: AccessScope.PUBLIC },
instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.MEDIUM),
monitoringConfiguration: { noMonitoring: true },
userData: UserData.forLinux(),
certificateProps: {
domainName: "domain-name-for-your-application.example",
},
scaling: {
minimumInstances: 1,
},
enabledDetailedInstanceMonitoring: true,
defaultInstanceWarmup: Duration.minutes(2),
});
Template.fromStack(stack).hasResource("AWS::AutoScaling::AutoScalingGroup", {
Properties: {
DefaultInstanceWarmup: 120,
},
});
});
});
11 changes: 11 additions & 0 deletions src/patterns/ec2-app/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,15 @@ export interface GuEc2AppProps extends AppIdentity {
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-monitoring.html
*/
enabledDetailedInstanceMonitoring?: boolean;
/**
* You can specify how long after an instance reaches the InService state it waits before contributing
* usage data to the aggregated metrics. This specified time is called the default instance warmup.
* This keeps dynamic scaling from being affected by metrics for individual instances that aren't yet
* handling application traffic and that might be experiencing temporarily high usage of compute resources.
*
* @see https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-default-instance-warmup.html
*/
defaultInstanceWarmup?: Duration;
}

function restrictedCidrRanges(ranges: IPeer[]) {
Expand Down Expand Up @@ -371,6 +380,7 @@ export class GuEc2App extends Construct {
instanceMetadataHopLimit,
updatePolicy,
enabledDetailedInstanceMonitoring,
defaultInstanceWarmup,
} = props;

super(scope, app); // The assumption is `app` is unique
Expand Down Expand Up @@ -423,6 +433,7 @@ export class GuEc2App extends Construct {
httpPutResponseHopLimit: instanceMetadataHopLimit,
updatePolicy,
enabledDetailedInstanceMonitoring,
defaultInstanceWarmup,
});

// This allows automatic shipping of instance Cloud Init logs when using the
Expand Down

0 comments on commit c4b0862

Please sign in to comment.