Simplify CloudWatch Alarms for Lambda Functions with AWS CDK
Preface
In this post, you’ll learn how to streamline your AWS CloudWatch alarm setup for multiple Lambda functions using AWS CDK. We’ll cover core CDK concepts, show you how to automate alarm creation, and demonstrate how to keep your infrastructure code DRY (Don’t Repeat Yourself). By the end, you’ll have a clear, scalable approach for monitoring Lambda errors across your projects.
Introduction
Imagine a fictitious website called GoalFront Auctions, where customers secretly place maximum bids for high-demand soccer match tickets. Because these auctions run on a short timer, speed and reliability are crucial. Any AWS Lambda error or delayed response could cause bidding failures, frustrated users, or lost revenue.
This post focuses on configuring CloudWatch alarms for Lambda errors, but the same approach applies to other critical metrics (like latency) across both stateful and stateless services. We’ll use AWS CDK to illustrate how to code your infrastructure and keep everything consistent, repeatable, and version-controlled.
Why
Consistent Monitoring: Automated alerts help you catch production issues before they escalate. In a high-traffic scenario such as GoalFront Auctions, a single overlooked error can disrupt user bids.
DRY and Maintainable: Writing alarm configurations for multiple Lambda functions can become unwieldy. AWS CDK lets you programmatically create and reuse alarm configurations, saving you from repetitive, brittle boilerplate.
Rapid Response: Linking alarms to SNS notifications ensures stakeholders get immediate alerts, enabling them to fix problems swiftly and keep the user experience seamless.
Build Example
1. Define Reusable Alarm Properties
First, create a helper function that returns the alarm configuration for Lambda errors. This reduces repetition and keeps your codebase tidy.
import { AlarmProps, ComparisonOperator } from "aws-cdk-lib/aws-cloudwatch";
export const lambdaErrors = (lambdaFunction: any): AlarmProps => {
return {
comparisonOperator: ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
threshold: 1,
evaluationPeriods: 1,
metric: lambdaFunction.metricErrors({ label: lambdaFunction.functionName }),
actionsEnabled: true,
alarmDescription: `This lambda has thrown an error: ${lambdaFunction.functionName}. ARN: ${lambdaFunction.functionArn}`,
alarmName: `${lambdaFunction.functionName}-Errors`,
};
};
Here, the alarm triggers if a Lambda function logs one or more errors in a given evaluation period. The alarm name and description automatically reference the function name, so any new Lambda uses the same logic.
2. Create an SNS Topic for Notifications
Next, define a dedicated SNS topic so your team can receive alerts the moment something fails.
import { aws_sns_subscriptions, CfnOutput, Stack, StackProps } from "aws-cdk-lib";
import { Topic } from "aws-cdk-lib/aws-sns";
import { Construct } from "constructs";
import { CDKContext } from "../../src/types";
export class ErrorReportingStack extends Stack {
public readonly servicesErrorsTopic: Topic;
constructor(scope: Construct, id: string, props: StackProps, context: CDKContext) {
super(scope, id, props);
// Create the SNS Topic
this.servicesErrorsTopic = new Topic(this, `${context.environment}-Errors-${context.appName}`, {
displayName: `${context.environment}-Errors-${context.appName}`,
});
// Subscribe your email addresses to the topic
this.servicesErrorsTopic.addSubscription(
new aws_sns_subscriptions.EmailSubscription("alerts@goalfrontauctions.com")
);
}
}
In this example, any triggered alarm tied to servicesErrorsTopic
will send email notifications to alerts@goalfrontauctions.com
.
3. Wire Everything Up in a Dedicated Alarms Stack
Finally, iterate over your Lambda functions, apply the reusable alarm configuration, and link each alarm to the SNS topic.
import { Alarm } from "aws-cdk-lib/aws-cloudwatch";
import { Stack, StackProps } from "aws-cdk-lib";
import { Construct } from "constructs";
import { SnsAction } from "aws-cdk-lib/aws-cloudwatch-actions";
import { Function as LambdaFunction } from "aws-cdk-lib/aws-lambda";
import * as alarmProps from "./alarm-props";
import { ErrorReportingStack } from "..";
import { CDKContext } from "../../src/types";
interface LambdaCloudWatchAlarmsStackProps extends StackProps {
errorReportingStack: ErrorReportingStack;
}
export class LambdaCloudWatchAlarmsStack extends Stack {
private alarms: Record<string, Alarm> = {};
constructor(scope: Construct, id: string, props: LambdaCloudWatchAlarmsStackProps, context: CDKContext) {
super(scope, id, props);
const { environment } = context;
const snsSendToServiceErrors = new SnsAction(props.errorReportingStack.servicesErrorsTopic);
// Modify this list to match your Lambda functions
const lambdaFunctionNames: string[] = ["bidProcessor", "bidValidator", "paymentHandler"];
lambdaFunctionNames.forEach((name) => {
const lambdaFunction = LambdaFunction.fromFunctionName(
this,
`${name}-${environment}`,
`${name}-${environment}`
);
// Create a CloudWatch alarm for each Lambda
this.alarms[`${name}Errors`] = new Alarm(
this,
`${name}Errors-alarm`,
alarmProps.lambdaErrors(lambdaFunction)
);
// Link the alarm to the SNS topic
this.alarms[`${name}Errors`].addAlarmAction(snsSendToServiceErrors);
});
}
}
After deploying this stack, each Lambda in lambdaFunctionNames
will have an associated “Errors” alarm. If a function fails, CloudWatch triggers the alarm, which then notifies your chosen email address.
Gotchas (Optional)
- Naming Conflicts: If you reuse the same function name across multiple environments, ensure your alarm names remain unique. Incorporate the environment name into your resource identifiers.
- SNS Subscription Confirmations: Remember that email recipients must confirm the SNS subscription email before receiving alerts.
- Alarm Thresholds: A threshold of
1
is sufficient to catch any Lambda error. However, for functions with transient or expected errors, consider adjusting the threshold and evaluation periods.
Conclusion
Monitoring Lambda functions is essential to keep mission-critical features—like the GoalFront Auctions bidding system—running smoothly. By automating CloudWatch alarm creation with AWS CDK and applying DRY principles, you’ll save development time, reduce code duplication, and ensure quick responses to issues.
Keep this approach in your toolbox for other AWS services or metrics that warrant proactive alerts. A robust monitoring strategy translates to a stable, user-friendly application—and a better overall developer experience.
My Technical Skills

AWS

JavaScript

TypeScript

React

Next.js

Cypress

Figma
