Skip to content

How to Create a CloudWatch Alarm for Lambda Functions Grouped by Tags Using SAM or CloudFormation

0

I am trying to create a CloudWatch alarm for a group of Lambda functions that share a specific tag (e.g., Environment=qa01 or ApplicationName=Energy).

Currently, the alarm works when I specify exact Lambda function names, but when I try to use tags in a CloudFormation (SAM) template, the invocation count is not increasing, and the alarm does not trigger.

Issue: The alarm does not trigger when using tags to group Lambda functions. The invocation count does not increase in CloudWatch when using SCHEMA("AWS/Lambda", FunctionName) WHERE Environment = 'qa01' or SEARCH('{AWS/Lambda,FunctionName} MetricName="Invocations" ApplicationName="Energy"'', 'Sum', 60). Exact function names work, but manually adding 100+ Lambda functions is not feasible. Question: Does CloudWatch Metrics Insights support filtering Lambda metrics by tags directly? If not, what is the recommended approach in CloudFormation/SAM to create alarms for multiple Lambda functions grouped by tags? Is there an alternative way to dynamically create alarms for all Lambda functions with a specific tag? Would appreciate any guidance on how to achieve this without manually listing function names. Here is my CloudFormation template:

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: AWS Serverless Specification framework for Lambda dashboards.

Resources:
  LambdaInvocationAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: Alarm when tagged Lambda functions are invoked more than 20 times in 10 minutes
      Metrics:
        - Id: m1
          Expression: SELECT SUM(Invocations) FROM SCHEMA("AWS/Lambda", FunctionName) WHERE Environment = 'qa01'
          Period: 60
      EvaluationPeriods: 1
      Threshold: 10
      ComparisonOperator: GreaterThanThreshold
      TreatMissingData: notBreaching
      AlarmActions:
        - !Ref AlarmNotificationTopic

  LambdaInvocationAlarmNew:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: LambdaInvocationAlarm
      AlarmDescription: Alarm when Lambda invocations exceed threshold for tagged functions
      Metrics:
        - Expression: 'SEARCH(''{AWS/Lambda,FunctionName} MetricName="Invocations" ApplicationName="Energy"'', ''Sum'', 60)'
          Id: e1
          ReturnData: true
      Threshold: 10
      ComparisonOperator: GreaterThanThreshold
      EvaluationPeriods: 1
      TreatMissingData: notBreaching
      AlarmActions:
        - !Ref AlarmNotificationTopic

  AlarmTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: cloudwatch.amazonaws.com
            Action: sns:Publish
            Resource: !Ref AlarmNotificationTopic
      Topics:
        - !Ref AlarmNotificationTopic

  AlarmNotificationTopic:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: LambdaInvocationAlarmTopic
2 Answers
0

Unfortunately, CloudWatch Metrics Insights does not directly support filtering Lambda metrics by tags. The approach you're trying with SCHEMA and SEARCH expressions in your CloudFormation template won't work as expected for tag-based filtering of Lambda functions.

However, there are alternative approaches you can consider to achieve your goal of creating alarms for multiple Lambda functions grouped by tags:

  1. Use a Lambda function to dynamically create and update alarms:

    • Create a Lambda function that periodically queries the Lambda API to get all functions with specific tags.
    • This function can then create or update CloudWatch alarms for each matching Lambda function.
    • Trigger this Lambda function on a schedule using EventBridge.
  2. Use AWS Config rules:

    • Create a custom AWS Config rule that identifies Lambda functions with specific tags.
    • Use the rule's output to trigger a Lambda function that creates or updates alarms.
  3. Utilize CloudFormation custom resources:

    • Create a custom resource in your CloudFormation template.
    • Implement a Lambda function as the backend for this custom resource.
    • The Lambda function can query for tagged Lambda functions and create alarms accordingly.
  4. Implement a CI/CD pipeline:

    • As part of your deployment process, query for Lambda functions with specific tags.
    • Dynamically generate CloudFormation templates with individual alarms for each function.

These approaches require more setup but offer the flexibility to create alarms based on tags. The best choice depends on your specific requirements and existing infrastructure.

For your CloudFormation template, instead of using tag-based filtering, you would need to explicitly list the Lambda function names or use one of the dynamic approaches mentioned above. Unfortunately, there's no direct way in CloudFormation to create a single alarm that monitors multiple Lambda functions based on tags.
Sources
Tags on Cloudwatch alarm for opsgenie | AWS re:Post
Create a CloudWatch alarm based on a metric math expression - Amazon CloudWatch

answered 2 years ago

0

Hi, you are right that Metrics Insights does not currently support filtering metrics by tags. The usual recommendation in your case is

  1. if you can express the same value than your tags as a dimension, as CloudWatch SQL engine and SEARCH functions are able to filter on dimension values, so it would be natively supported. It is however only possible on custom metrics, where you have full control over the dimensions and their values, vended metrics are defined by the services that emit them.
  2. if your resources are stable or it is easy for you to automate actions on the lifecycle on your resources, implement a lambda function to create, update or delete alarm definitions when the resources you want to alarm on vary, that’s pretty much what point 1 in the previous answer above corresponds to.
  3. if your resources are very dynamic like autoscaled instances, use external sources querying with a custom lambda that retrieves the list of resources from the tags by querying the resource group API, and use that list of resources to call CloudWatch GetMetricData for the corresponding metrics, do any preaggregation if you need, and forward the data in the output of the lambda.

That being said, both of those options 2 and 3 require some custom work. If you need it built-in as a standard feature and can’t go for option 1, the best way is if you have access to AWS support, to open a case to raise a feature request.

AWS

answered 2 years ago

EXPERT

reviewed 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.