How to Attach a CloudWatch Alarm to a Lambda Function
Tags: aws, lambda, learninpublic, beginners
Published: 2023-02-13 12:45:00

In this post, we'll learn how to attach a CloudWatch alarm to a Lambda function in two ways: through the AWS console and using the Serverless framework.

If you prefer to watch a video you can view it below:

{% embed https://youtu.be/sydhU7sIgN0 %}

## Example Lambda

For reference, we are going to use the following lambda function:

```
module.exports.handler = async (event) => {
  if (Math.random() < 0.5) {
    throw new Error();
  }
  const response = {
    statusCode: 200,
    body: JSON.stringify('Hello from Lambda!'),
  };
  return response;
};
```

The above function errors about 50% of the time. For this example, I scheduled the function to run every minute, so that we can quickly test it. To learn how to schedule a function on a timer you can look at my post [here](https://dev.to/aws-builders/how-to-trigger-a-lambda-on-a-timer-via-aws-console-serverless-framework-2n6i).

Create the function via the console and name it `ErroringLambda` make sure to attach a trigger to the function that has it run every 1 minute.

## Method 1: Attach a CloudWatch Alarm to a Lambda Function Via the AWS Console

After creating the function and scheduling the function, go to the CloudWatch section of the AWS console. Click "All Alarms" on the side menu. If you have no alarms your CloudWatch will look like below (otherwise you'll see the alarms already in your account).

![CloudWatch with No Alarms](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/snspzokjwt8bslogttfn.png)

Click the Create Alarm button. You'll be asked to specify a metric. Click "Select Metric" and then in the Metrics Section chose "Lambda", then "By Function Name".  Select the "Errors" metric for our `ErroringLambda` function.

![Selecting the ErroringLambda function Errors Metric](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3uf023c7h0ofix8nvkcl.png)

We are going to set the alarm to trigger if the sum of errors is greater than or equal to 3 within a 5-minute period. In the additional configurations you can treat missing data in a few different ways, in this example we will treat it as breaching.

![Defining Metrics and Threshold](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pamfwk7te3pwstg0h3d2.png)

Click next and set up a notification to send an email through an SNS topic. Choose "Create new topic" and define your topic's name and the email you want to send it to. 

Click next and give a name to your cloud watch alarm and click next. Finally review the alarm you created and then click "Create alarm".

Congrats you've just attached a CloudWatch Alarm to a Lambda Function Via the AWS Console. Be sure to check your email to confirm your subscription to the SNS topic (it could be in your spam).

## Method 2: Attach a CloudWatch Alarm to a Lambda Function Via the AWS Console

Now, let's translate this process to using the Serverless framework. We'll define our function in the `severless.yml` file, and use the "resources" property to define our CloudWatch alarm using a CloudFormation template. This includes defining our SNS topic, CloudWatch alarm, and SNS subscription (in this case, an email endpoint).

The resources property in Serverless framework allows you to add other AWS infrastructure resources which the AWS Lambda functions in your Service depend on, like AWS DynamoDB or in this case Cloud Watch Alarms. In the resources property, you can add raw CloudFormation template syntax. Below is the `severless.yml`:

```
service: aws-lambda-cloud-watch-example
frameworkVersion: '3'

provider:
  name: aws
  runtime: nodejs18.x

functions:
  erroringLambda:
    handler: index.handler
    events:
      - schedule: rate(1 minute)

resources: #Cloudformation template syntax
  Resources:
    TopicErroringLambdaAlarm:
      Type: AWS::SNS::Topic
      Properties:
        TopicName: erroring-lambda-topic-cloudwatch-alarm

    ErroringLambdaAlarm:
      Type: AWS::CloudWatch::Alarm
      Properties:
        AlarmDescription: Example Alarm for Lambda Errors
        Namespace: AWS/Lambda
        MetricName: Errors
        Statistic: Sum
        Threshold: 3
        ComparisonOperator: GreaterThanOrEqualToThreshold
        EvaluationPeriods: 1
        Period: 300
        TreatMissingData: breaching
        AlarmActions: 
          - !Ref TopicErroringLambdaAlarm
        Dimensions:
          - Name: FunctionName
            Value: erroringLambda

    TopicErroringLambdaAlarmSubscription:
      Type: AWS::SNS::Subscription
      Properties:
        Endpoint: <ADD EMAIL HERE>
        Protocol: email
        TopicArn: !Ref TopicErroringLambdaAlarm
```

Let's inspect this YAML file a little. 

The first resource `TopicErroringLambdaAlarm` defines the SNS Topic, as we did in the AWS Console walkthrough. In this case, we are just declaring an SNS Topic so that the CloudWatch alarm we define next has a way to alert.

The second resource `ErroringLambdaAlarm` is the definition for our CloudWatch alarm, here you can see that the `Namespace` and `MetricName` is AWS/Lambda and Errors. This is the same as what we defined earlier in our AWS Console walkthrough. The `Threshold` is 3 and the `ComparisonOperator` is `GreaterThanOrEqualToThreshold` this is just like the options we chose earlier. Hopefully, you can see the connection to the AWS Console. Now the `Period` is set to 300 this is because the period is defined in seconds so in order to be 5 mins it would be 300 seconds. Our `AlarmActions` refers to the `TopicErroringLambdaAlarm` we defined above, and finally, our alarm's `Dimensions` refer to the `erroringLambda` defined in our `severless.yml` file.

The last resource is the `TopicErroringLambdaAlarmSubscription` this defines the Subscription that the SNS Topic triggers when the CloudWatch alarm triggers it, right now we are just sending an email, but you can enhance this subscription (for example connect to PagerDuty to alert someone on call). 

So now you know how to attach a CloudWatch alarm to a Lambda function, both through the AWS console and using the Serverless framework. By using the Serverless framework, we can easily manage our CloudWatch alarms in a scalable and efficient manner.

This is just the tip of the iceberg that is a lot more you can do with CloudWatch Alarms, such as monitor if resources are costing more that you would like, if resources are optimized correctly, configure an alarm based on "anomaly detection" where CloudWatch will analyze past metric data to create a model of expected values and alert on deviations from that baseline, etc. Be sure to check out the CloudWtach documentation to learn more!

Happy Learning!