我们在使用AWS时偶尔会在管理员邮箱中收到AWS发的通知邮件,比如关于EC2维护信息,这些邮件很容易淹没在收件箱中,没有得到及时处理。另外对于重要的应用我们可能会在CloudWatch设置一些指标告警并进行邮件通知。如果这些都可以发到微信或钉钉等即时通信软件,就比邮件通知好多了,毕竟很多人都习惯在微信等即时通信软件上查看消息。

其实具体实现原理并不复杂,我们知道微信或钉钉等即时通信工具均提供了消息接口。第三方应用获取授权后,通过调用这些接口即可往客户端发送消息。在AWS上可以在EventBridge/Cloudwatch Event中配置事件规则,即可以触发一个Lambda运行微信/钉钉接口调用的处理逻辑。通过Serverless是可以简单地实现这个通知告警机制的。

介绍这块相关的博客和文档已经很多了,但操作起来都相对麻烦一些,还要自己照着文档配置Lambda,复制粘贴别人的代码,改参数啥的,然后还要各种调试。能不能我就点几下鼠标,配置自己微信接口的几个参数上去,AWS就可以把告警通知自动配置好了?如果有一些新的告警事件想推送到微信,我们也可以在控制台上设置好规则,不用去修改Lambda的代码那么罗嗦。

如果你也跟我一样这么懒的话,那接下来这个Serverless应用应该对你有帮助:

部署微信告警应用

这个Serverless应用提供一个无须编写代码便可快速部署微信告警通知的功能。你可以在AWS控制台进到 Serverless Application Repository(SAR)这个服务(有点像AppStore,只是这个应用商店是专门放基于Serverless应用的,AWS的用户都可以在上面提交),然后搜索 wechat,就可以找到这个应用 WeChat-Notifier

搜索SAR

记得打上上图那个的勾勾。因为应用会部署这两个演示的EventBridge的Rule,需要创建从EventBridge到SNS的Publish权限。另外目前国外区域和国内北京区域均可直接通过SAR部署,如果需要在宁夏区域部署可私信我

点击这个应用名字就可以进入部署页面,填入三个跟微信接口相关的参数:

填写参数

点击最下方的Deploy 按钮,即可快速部署整套微信告警通知的相关组件。(这三个参数是从企业微信那边获得,如果你还没有创建出企业微信应用,那可以参考文末的附录)

这个应用会自动部署一系列的组件,涉及的 AWS 服务包括 EventBridge, SNS, Lambda 和 Secrets Manager 等。如下是整体的部署架构:

整体部署架构

注意到这里使用了 Secrets Manager 保存了企业微信应用的 Secret 参数。因为该参数较为敏感,因此通过 Secrets Manager 来进行加密存储并由Lambda程序通过API进行访问。

为方便演示EventBridge功能,这个应用部署时创建了两个EventBridge的Rule,一个是捕获EC2的状态变化事件(如开关机),另一个是捕获AWS健康事件(如EC2计划维护事件)。

测试微信告警功能

部署成功后我们可以来测试一下了:

通过 SNS 直接进行告警消息发送

我们可以尝试一下直接往SNS里发消息,这样SNS就会触发 Lambda 去将消息发送至微信客户端。首先我们在 Lambda 的控制台里找到刚才部署的应用,然后就可以找到该应用对应的 SNS Topic :
SNS Topic

接着在 SNS 控制台里直接进行消息发送,在Message Body里填入要发送的消息即可

在微信端就可以收到刚才的消息了:

因此,后续其他应用如果需要发送消息至微信,则可以将其与SNS进行对接,这样就可以很方便的进行微信告警而无须额外增加处理代码。

通过 EventBridge 捕获 AWS 相关事件并进行告警

如前面所述,这个应用部署了两个示例的规则,分别是捕获AWS健康事件和EC2状态变更事件,同样可以在 Lambda 控制台中找到这两个规则:

接下来以EC2状态变更事件为例来看一下EventBridge规则的编写。在EventBridge的控制台上我们可以看到 Event Pattern

{
  "detail-type": ["EC2 Instance State-change Notification"],
  "source": ["aws.ec2"],
  "detail": {
    "state": ["running", "stopped", "terminated"]
  }
}

上面这个JSON并不需要自己手写,通过 EventBridge 的控制台我们可以很方便定义 AWS相关服务的 Event Pattern :

在控制台上我们也可以看到示例的事件是什么样的,比如说实例启动后进入 running 状态,EventBridge就会发出如下事件:

{
  "version": "0",
  "id": "ee376907-2647-4179-9203-343cfb3017a4",
  "detail-type": "EC2 Instance State-change Notification",
  "source": "aws.ec2",
  "account": "123456789012",
  "time": "2015-11-11T21:30:34Z",
  "region": "us-east-1",
  "resources": ["arn:aws:ec2:us-east-1:123456789012:instance/i-abcd1111"],
  "detail": {
    "instance-id": "i-abcd1111",
    "state": "running"
  }
}

在选好 Event Pattern 后,我们就可以指定捕获的事件要触发什么样的 Target,这里我们选择了把事件消息打到 SNS :

注意到这里我们使用了 Input Transformer, 也就是说我们可以通过配置这个转换器,来将事件的JSON转换成一个可读性比较强的文本,然后再发给SNS。这个功能可以非常灵活地进行输入转换,在很多场景下可以不需要额外的代码就可以实现灵活的数据转换了。

接下来我们就启动一台EC2实例,在微信端就可以看到相关的告警信息了:

通过EventBridge可以方便地增加Rule,以便捕获所关心的事件类型,并将相关告警消息发送至微信。同时,其他的AWS服务,如CloudWatch等也可以将告警信息发送至SNS,甚至本地数据中心或其他云上,也可以利用SNS来进行微信消息的推送。相关架构图如下所示:

附:配置企业微信应用

首先登录企业微信管理后台,创建一个新的应用,并记录 AgentId 和 Secret

接着记录企业ID:

这三个信息就是前面部署微信告警应用所需要的三个参数了。
另外如果我们希望从微信客户端直接接收告警消息,而不想去使用企业微信客户端的话,可以考虑使用微信插件:

致谢

本项目使用的企业微信对接代码是在 Niko Feng 一个企业微信对接的Lambda Layer基础上增加了异常处理和将密钥保存在Secrets Manager等调整,在SAR中可以找到 Niko 提供的这个Lambda Layer:

同时 Niko Feng 也提供了一个与方便与钉钉进行对接,同样在SAR中也可以找到:

在此对 Niko 表示感谢!


本文最早发表在个人的微信公众号,对云技术感兴趣的朋友也可以关注我的微信公众号(CloudBuilder)与我交流

qrcode_for_gh_ec453322f1e2_258.jpg


Randy
1 声望0 粉丝