如何将CloudWatch警报连接到Lambda函数

19

如何将AWS CloudWatch警报连接到Lambda函数调用?

我正在通过AWS CloudFormation模板以编程方式向我们创建的ELB添加CloudWatch警报,作为CloudFormation堆栈的一部分。我希望将警报发送到一个Lambda函数,该函数将把消息发布到Slack。虽然警报起作用,并且SNS配置对我来说似乎是正确的,但Lambda函数从未被调用。

Lambda函数遵循这些示例:

https://medium.com/cohealo-engineering/how-set-up-a-slack-channel-to-be-an-aws-sns-subscriber-63b4d57ad3ea#.x2j9apedu

http://inopinatus.org/2015/07/13/hook-aws-notifications-into-slack-with-a-lambda-function/

Lambda函数已经运行,我可以通过AWS控制台发送测试数据并将其发布到Slack。
负载均衡器已创建,并配备了正确的Cloud Watch警报。

enter image description here

警报似乎已配置为将警报发送到正确的SNS主题:

enter image description here enter image description here

有一个针对该主题的 SNS 订阅,其中 Lambda 函数是其终端点:

enter image description here

警报被触发并发送到正确的主题,当警报触发时:

enter image description here

但是 lambda 函数从未被调用:

enter image description here

然而,如果我在Lambda函数上手动将SNS主题添加为“事件源”,则当警报触发并发布Slack消息时,它会被调用。

enter image description here

我是否误解了如何将 CloudWatch 警报连接到 Lambda 函数?还是有一些细节我忽略了?
如果这种方法行不通,而将 Lambda 函数连接到 CloudWatch 警报的唯一方法是将 SNS 主题添加为“事件源”,那么通过 AWS CloudFormation 模板应该如何适当地完成呢?我没有看到明显的方法来修改现有资源,如固定 Lambda 函数。
以下是我的 CloudFormation 模板:
"GenericSlackAlertSNSTopic" : {
    "Type" : "AWS::SNS::Topic",
    "Properties" : {
        "Subscription" : [ {
            "Endpoint" : "arn:aws:lambda:us-east-1:[...]:function:snsToSlack",
            "Protocol" : "lambda"
        } ]
    }
},
"ELBNoTrafficAlarm": {
    "Type": "AWS::CloudWatch::Alarm",
    "Properties": {
        "Namespace" : "AWS/ELB",
        "AlarmDescription": "Alarm for no apparent traffic on an ELB.",
        "AlarmActions": [{
            "Ref": "GenericSlackAlertSNSTopic"
        }],
        "InsufficientDataActions": [{
            "Ref": "GenericSlackAlertSNSTopic"
        }],
        "MetricName": "RequestCount",
        "Statistic": "Sum",
        "Dimensions" : [ {
            "Name" : "LoadBalancerName",
            "Value" : { "Ref" : "ElasticLoadBalancer" }
        } ],
        "Period": "60",
        "EvaluationPeriods": "3",
        "Threshold" : "10",
        "ComparisonOperator": "LessThanOrEqualToThreshold"
    }
}

谢谢!

-neil


我今天自己设置了这个,所以可以确认它是有效的。但我不明白为什么你所做的不行。 - James Ogden
谢谢。这不是CloudFormation创建的问题,我已经启动了大约10次堆栈,结果都一样(即没有Lambda函数调用)。 - Neil Cronin
进入控制台中的CloudFormation并验证SNS主题是否设置。如果发生错误,它应该在那里显示。除此之外,这对我来说看起来是正确的... - Chris Franklin
CloudFormation “Events” 选项卡中未记录任何错误。14:53:34 UTC-0800 CREATE_COMPLETE AWS::SNS::Topic GenericSlackAlertSNSTopic 物理 ID:arn:aws:sns:us-east-1:[...]:v[...]-GenericSlackAlertSNSTopic-[...]8ZEX - Neil Cronin
@JamesOgden 如果你们中任何一位有一个可分享的工作云形成模板,你介意编辑并发布它吗?谢谢! - Neil Cronin
显示剩余2条评论
6个回答

8
AWS最近发布了一个使用Python和Nodejs的Lambda将Slack与AWS Cloudwatch集成的蓝图,链接如下:https://aws.amazon.com/blogs/aws/new-slack-integration-blueprints-for-aws-lambda/。然而,按照蓝图中提到的步骤,我也遇到了与你相同的问题,除非我手动将SNS主题作为“事件源”添加到Lambda函数中,否则我无法收到警报。进一步的调查引导我找到了这个问题:Can't create a SNS Event source on a Lambda function using CloudFormation。最后,通过阅读AWS文档,得出以下结论: 1)http://docs.aws.amazon.com/lambda/latest/dg/intro-core-components.html Amazon SNS通过主题订阅配置来维护事件源映射(没有AWS Lambda API来配置此映射)。
2)http://docs.aws.amazon.com/sns/latest/dg/sns-lambda.html 使用AWS管理控制台配置带有Lambda端点的Amazon SNS
因此,目前订阅应通过AWS管理控制台完成。总结:目前配置Amazon SNS与Lambda端点的唯一方法是通过AWS管理控制台。附加奖励:类似的问题,答案也相同:AWS Lambda scheduled event source via cloudformation

3

现在,您可以使用 AWS EventBridge(CloudWatch 事件的重命名和扩展版本)来更轻松地完成此操作!有关详细信息,请参见此处

它与 SNS 类似,但似乎更容易使用。

它还提供了一些内置选项,可用于筛选触发 Lambda 的事件。


2

在编写时,为了将CloudWatch警报连接到Lambda,您需要一个SNS主题

CloudWatch警报将使用SNS主题作为警报操作,并且SNS主题需要除订阅指定主题的Lambda外,还需要拥有lambda:Invoke权限。

CloudFormation模板

假设您在CloudFormation模板中拥有CloudWatch警报和Lambda ARN(ARN字符串或同一模板中的资源),则可以使用资源AWS :: Lambda :: PermissionAWS :: SNS :: Topic将它们连接起来。

例如,使用以下示例(添加默认Lambda ARN值):

  • aws cloudformation create-stack --stack-name MyTest --template-body file://mytest.yaml
AWSTemplateFormatVersion: '2010-09-09'

Parameters:

  LambdaArn:
    Type: String
    Description: The lambda arn, if lambda resource is in template change !Ref LambdaArn with !GetAtt LogicName.Arn
    Default: "[YOUR ARN]"

Resources:

  DummyTopic:
    Type: "AWS::SNS::Topic"
    Description: "sns topic to complete this dummy template, remove it when changing the cloudwatch alarm"
    Properties:
      TopicName: "mytest"

  CloudWatchAlarmInvocationAlarm:
    Type: "AWS::CloudWatch::Alarm"
    Description: "DummyAlarm change it (mainly Namespace, MetricName and Dimensions) to achieve your goal"
    Properties:
      Namespace: "AWS/SNS"
      AlarmDescription: "Dummy alarm"
      AlarmActions:
        - !Ref NotificationTopic
      MetricName: NumberOfMessagesPublished
      Statistic: "Sum"
      Dimensions:
        - Name: TopicName
          Value: !GetAtt DummyTopic.TopicName
      Period: 60
      EvaluationPeriods: 1
      Threshold: 1
      ComparisonOperator: "GreaterThanOrEqualToThreshold"
      TreatMissingData: notBreaching   # missing data points will not trigger the alarm => maintain

  NotificationTopic:
    Type: "AWS::SNS::Topic"
    Description: "Sns topic that communicates directly with the lambda"
    Properties:
      TopicName: "MyNotificationTopic"
      Subscription:
        - Endpoint: !Ref LambdaArn
          Protocol: "lambda"

  LambdaInvokePermission:
    Type: "AWS::Lambda::Permission"
    Properties:
      FunctionName: !Ref LambdaArn
      Action: "lambda:InvokeFunction"
      Principal: "sns.amazonaws.com"
      SourceArn:  !Ref NotificationTopic


1

CloudWatch定时事件现在具有Lambda和本地目标。在此输入图片描述

同时,您可以为Lambda在CloudFormation中添加计划事件。

EventListFunction:
  Type: 'AWS::Serverless::Function'
  Properties:
    ...
    Events:
      Schedule1:
        Type: Schedule
        Properties:
          Schedule: rate(1 day)

1

请确保您授予SNS主题调用Lambda函数的权限。权限的CloudFormation示例如下:

"LambdaInvokePermission": {
    "Type": "AWS::Lambda::Permission",
    "Properties": {
        "FunctionName" : "arn:aws:lambda:us-east-1:[...]:function:snsToSlack",
        "Action": "lambda:InvokeFunction",
        "Principal": "sns.amazonaws.com",
        "SourceArn": { "Ref": "GenericSlackAlertSNSTopic" }
    }
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接