in cdk/lib/podcasts-rss.ts [16:124]
constructor(scope: App, id: string, props: GuStackProps) {
super(scope, id, props);
const urgentAlarmTopicArn = aws_ssm.StringParameter.fromStringParameterName(this, "urgent-alarm-arn", "/account/content-api-common/alarms/urgent-alarm-topic");
const nonUrgentAlarmTopicArn = aws_ssm.StringParameter.fromStringParameterName(this, "non-urgent-alarm-arn", "/account/content-api-common/alarms/non-urgent-alarm-topic");
const vpcId = aws_ssm.StringParameter.valueForStringParameter(this, this.getVpcIdPath());
const vpc = Vpc.fromVpcAttributes(this, "vpc", {
vpcId: vpcId,
availabilityZones: ["eu-west-1a","eu-west-1b" ,"eu-west-1c"]
});
const subnetsList = new GuParameter(this, "subnets", {
description: "Subnets to deploy into",
default: this.getDeploymentSubnetsPath(),
fromSSM: true,
type: "List<String>"
});
const deploymentSubnets = GuVpc.subnets(this, subnetsList.valueAsList);
const hostedZone = aws_ssm.StringParameter.valueForStringParameter(this, `/account/services/content-aws.guardianapis/${this.stage}/hostedzoneid`);
const app = new GuPlayApp(this, {
access: {
scope: AccessScope.PUBLIC,
},
app: "podcasts-rss",
applicationLogging: {
enabled: true,
},
certificateProps: {
domainName: this.stage==="CODE" ? "podcast-feed.content.code.dev-guardianapis.com" : "podcast-feed.content-aws.guardianapis.com",
hostedZoneId: hostedZone,
},
instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.SMALL),
monitoringConfiguration: {
snsTopicName: urgentAlarmTopicArn.stringValue,
http5xxAlarm: {
tolerated5xxPercentage: 20,
numberOfMinutesAboveThresholdBeforeAlarm: 2,
},
unhealthyInstancesAlarm: true,
},
privateSubnets: deploymentSubnets,
publicSubnets: deploymentSubnets,
roleConfiguration: {
additionalPolicies: [policies(this)],
},
scaling: {
minimumInstances: 2,
maximumInstances: 20,
},
userData: {
distributable: {
fileName: "podcasts-rss_1.0_all.deb",
executionStatement: "dpkg -i /podcasts-rss/podcasts-rss_1.0_all.deb"
}
},
vpc,
});
app.loadBalancer.addListener("HttpToHttps", {
protocol: ApplicationProtocol.HTTP,
port: 80,
defaultAction: ListenerAction.forward([app.targetGroup])
});
const cpuHighAlarm = new Alarm(this, "HighCPU", {
actionsEnabled: true,
alarmDescription: "CPU utilization alarm for autoscaling",
comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
datapointsToAlarm: 5,
evaluationPeriods: 5,
metric: new Metric({
dimensionsMap: {
AutoScalingGroupName: app.autoScalingGroup.autoScalingGroupName,
},
metricName: "CPUUtilization",
namespace: "AWS/EC2",
period: Duration.minutes(1),
statistic: "Average",
}),
threshold: 50,
treatMissingData: TreatMissingData.MISSING,
});
const scaleUpStep = new StepScalingAction(this, "ScaleUp", {
adjustmentType: AdjustmentType.PERCENT_CHANGE_IN_CAPACITY,
autoScalingGroup: app.autoScalingGroup,
cooldown: Duration.minutes(5),
});
scaleUpStep.addAdjustment({
lowerBound: 0,
adjustment: 100
});
cpuHighAlarm.addAlarmAction(new AutoScalingAction(scaleUpStep));
const scaleDownStep = new StepScalingAction(this, "ScaleDown", {
adjustmentType: AdjustmentType.CHANGE_IN_CAPACITY,
autoScalingGroup: app.autoScalingGroup,
cooldown: Duration.minutes(5),
});
scaleDownStep.addAdjustment({
lowerBound: 0,
adjustment: -1,
});
cpuHighAlarm.addOkAction(new AutoScalingAction(scaleDownStep));
}