亚马逊AWS官方博客

基于 Amazon Connect 构建运维告警系统

背景介绍

在基础设施的选择上,很多用户选择多云部署,云端与线下数据中心结合的方式来最大限度的整合优势资源,保证应用程序的高可用和低成本。在日常运维的过程中,用户不可避免的接触不同平台的资源与告警系统,对运维和安全工作提出了挑战。尤其是在高级别告警发生的时候,告警系统需要在第一时间用电话的方式直接联系运维与安全人员,这就要保证电话告警系统的可靠性和高可用性。同时在多应用,多项目的场景中,需要按照应用与项目区分负责的运维人员。由于告警,尤其是高级别告警并非是持续发生,对应的成本也需要控制在合理范围内。

Amazon Connect 是亚马逊构建的云联络中心服务。本文主要介绍利用 Amazon Connect 的电话外呼功能,结合 Amazon SQS,Amazon DynamoDB,AWS Lambda 这三种无服务器服务,构建低成本,高可用的电话告警系统。并且方便多云与线下数据中心的接入。

解决方案架构

本文解决方案利用 Amazon SQS 队列做为接受告警信息的消息队列,使用 Amazon DynamoDB 表按应用或项目储存相应运维人员的电话,并储存每次告警事件的记录。由 AWS Lambda 函数按事件触发 Amazon Connect 流,实现电话告警。

简要流程:

  1. 告警系统将事件加入 Amazon SQS 队列,触发 AWS Lambda 函数。
  2. AWS Lambda 函数从 Amazon DynamoDB 通讯表中获取电话号码并触发 Amazon Connect 流。
  3. Amazon Connect 拨打相应的运维人员电话。
  4. AWS Lambda 函数将事件记录到 Amazon DynamoDB 事件表,如果呼叫未得到应答,函数会向原队列发回一条带有可见性延迟的消息。
  5. 消息在队列中可见时再次触发 AWS Lambda 函数,向上一级的运维人员继续打电话,以此类推直到被接听或触发设置的上限。

至此,无论用户的应用在其他云服务商或者线下数据中心,客户只需要配置相应的 Amazon SQS 队列权限,就可以接入到这个电话告警系统,并将每次事件的电话告警记录保存在 Amazon DynamoDB 表中。这个架构中使用的 Amazon SQS,Amazon DynamoDB,AWS Lambda 均为无服务器资源,保证了服务的可靠性、可用性的同时,极大的降低了使用与维护成本。

先决条件

  1. 创建 Amazon Connect 实例

从 AWS 控制台进入 Amazon Connect 服务页面,选择添加实例, 我们需要创建一个有对外呼出功能的实例,具体配置步骤参考此处文档。注意在设置通话时,通话选项为允许出站呼叫。

创建成功后,通过 Amazon Connect 页面进入 Instance,显示状态为活跃。

  1. 申请源电话号码

点击进入访问 URL, 通过上一步中管理员账户登陆。在左侧列表申请对外拨打的源电话号码。根据要拨打的对象国家,选择合适的源号码属地,对应列表参考此处文档。本文选择了泰国的免费电话进行测试,如下图所示。

服务部署

  1. 创建流

从 Amazon Connect 管理页面通过访问 URL 进入服务页面,使用管理员身份登录。从左侧菜单中选择流,点击创建联系流,进入流页面。在流页面右上选择导入选项。

将下面的配置代码复制粘贴到本地 demo.txt 文档,选择此 demo.txt 文档导入。

代码链接

导入后可见如下流页面:

  1. 创建 Amazon SQS 队列

Amazon SQS 队列用于触发 AWS Lambda 函数,同时可使用死信队列 DLQ 接收无法交付的消息。

进入 Amazon SQS 页面,点击创建队列。输入队列名称 demo_queue_amazon_connect_dlq,其他选择为默认即可,点击创建队列。此队列将作为死信队列。

待队列创建完成,进入 Amazon SQS 页面,点击创建队列。输入队列名称 demo_queue_amazon_connect。 配置可见性超时为 90 秒,这保证了可见性超时大于 AWS Lambda 函数的超时数值。死信队列 ARN 为上面 demo_queue_amazon_connect_dlq 队列 ARN,其他配置保持不变,点击创建队列。

创建完成状态如下图所示:

  1. 创建 Amazon DynamoDB 通讯表

此表用于根据不同的项目名称存储运维团队电话号码。假设每个项目都有一个 3 层的运维支持团队,当第一层运维人员没有接到告警电话后,Amazon Connect 会获取上一层的运维人员电话,继续拨打。

进入 Amazon DynamoDB 界面,点击创建表。输入表名称 connect-contact-info。 输入分区键名称 projectName。选择自定义设置,表类为 DynamoDB 标准,读/写容量设置为按需。其他配置为默认,点击创建表。

表创建成功后,点击操作,选择创建项目,输入项目名称 project1。 点击添加新属性,选择字符串,并输入 3 层运维人员电话。点击创建项目。

  1. 创建 Amazon DynamoDB 事件表

此表用于存储 Amazon Connect 的外呼事件。

进入 Amazon DynamoDB 界面,点击创建表。输入表名称 connect-event-info。 输入分区键名称 eventId。选择自定义设置,表类为 DynamoDB 标准,读/写容量设置为按需。其他配置为默认,点击创建表。

  1. 创建 AWS Lambda 函数

从 AWS 控制台进入 AWS Lambda 函数,点击创建函数。输入函数名称 amazon_connect_function。选择 python3.9 运行时环境,其他参数为默认。点击创建函数。

点击配置,选择常规配置,编辑超时时间为 1 分 15 秒。由于 Amazon Connect 在做 start_outbound_voice_contact API 呼叫时超时为 60 秒,在代码中我们配置了 65 秒的 sleep 时间,用来抓取外呼电话是否被接听。

在同页面点击权限,选择角色名称进入 AWS IAM 管理页面。点击添加权限,创建内联策略。此处我们要创建三个内联策略给 AWS Lambda 函数赋权,分别对应 Amazon Connect 权限,Amazon DynamoDB 表权限,和 Amazon SQS 队列权限。点击进入 JSON 模式,配置策略如下:

  • Amazon Connect 权限 JSON 模板:策略代码链接,复制后替换 Resource 中 ARN。
  • Amazon DynamoDB 权限 JSON 模板:策略代码链接, 复制后替换 Resource 中 ARN。
  • Amazon SQS 队列权限 JSON 模板:策略代码链接,复制后替换 Resource 中 ARN。

配置后如下图:

返回 AWS Lambda 函数页面,点击配置,选择触发器,选择添加触发器。选择的 Amazon SQS 队列作为触发源,选择之前创建 demo_queue_amazon_connect 队列 ARN,将批处理大小设置为 1。完成后点击添加。本文提供的 AWS Lambda 函数代码不包含批处理逻辑。

点击进入函数,将下面的代码复制到 lambda_function.py 中,点击 Deploy 生效。

代码链接

根据之前创建的资源,更新代码中的 Global Variable 部分:

  • InstanceId 是 Amazon Connect 的实例 id
  • ContactFlowId 是 Amazon Connect 流 id
  • SourcePhoneNumber 是从 Amazon Connect 申请到的源电话号码
  • QueueUrl 是 Amazon SQS 消息队列的 URL
  • ContactInfoTableName 是 Amazon DynamoDB 通讯表的名字
  • EventTableName 是 Amazon DynamoDB 事件表的名字
  • ContactLayer 是在 Amazon DynamoDB 通讯表中一个项目里面联系人数量
  • RoundCallLimit 是在电话未接通的情况下,需要重复呼叫几轮联系人
  • DelaySeconds 是指在电话未接通的情况下,AWS Lambda 函数将事件重新放回队列中,间隔多久变为可见,被函数重新处理

  1. 配置告警权限

在告警端配置权限,告警服务器只需要将告警事件发送到队列的权限。可以通过创建 AWS IAM 用户实现。

从管理控制台进入AWS IAM 页面,选择用户,添加用户,输入用户名 demo-connect-user。 此用户我们将不会用于管理控制台登录。点击下一步,使用默认设置。在此处不需添加任何权限,点击下一步,选择创建用户。

创建成功后, 选择该用户,点击添加权限,创建内联策略,选择 JSON,复制如下策略到 JSON 中,复制后替换 Resource 中 ARN。

策略代码链接

点击查看策略,输入策略名称 demo-connect-policy, 点击创建策略。

点击安全凭证,创建访问密钥,选择本地代码,点击下一步。描述标签可填写 demo-connect。点击创建访问密钥,将访问密钥保存到本地使用。此处 AWS IAM 用户密钥将用于测试,AWS IAM 权限管理安全最佳实践请参考此处文档

测试告警

将得到的 IAM 用户密钥 aws_access_key_idaws_secret_access_key 配置到本地 ~/.aws/ credentials 中,此处我们资源部署使用在 ap-southeast-1 区域,并将输出定为 json 格式。

[demo-connect-user]
aws_access_key_id=<your access key>
aws_secret_access_key=<your secret access key>
region = ap-southeast-1
output = json

我们使用 AWS 提供的 Python SDK 环境进行测试,配置环境参考此处文档。配置完成后将以下测试代码复制粘贴到 test.py 中。更新其中 QueueUrl 变量,可以从 Amazon SQS 管理页面获取此 URL。

代码链接

运行测试脚本,此处测试成功打通电话,我们可以选择不接起电话,此时程序会从 Amazon DynamoDB 通讯表中获取上一层运维人员电话,继续拨打,直到接通。

接通后按 1 听取留言。

此时我们查看 Amazon DynamoDB 事件表 connect-event-info 中会有事件已经相关的电话记录:

进入项目可以看到每次 Amazon Connect 拨打的 ContactId

同时我们也可以根据 eventIdContactId 在 AWS Lambda 函数的日志中查找相关记录。

总结

本文展示了通过使用 Amazon SQS,Amazon DynamoDB,AWS Lambda 这三种无服务器服务,配合 Amazon Connect 搭建多层级运维告警系统,使用简单的 AWS IAM 用户配置,打通多云及线下数据中心的告警需求。

参考资料

本篇作者

曾鑫

AWS 解决方案架构师,负责基于 AWS 云平台的解决方案咨询和设计,对 AWS 安全产品的使用与整合有多年实践经验。

谭继聪

亚马逊云科技解决方案架构师,负责基于 AWS 云计算方案架构的咨询和设计,并专注于数据库和数据分析技术方向。