亚马逊AWS官方博客
使用 AWS serverless 服务搭建基于 Gitlab 和飞书的 CICD 审批流
背景介绍
很多公司的软件开发团队都会使用一些 SaaS 或者自建的开源 Git 平台来管理代码,比如说 GitHub 或者 Gitlab,并且基于该平台的能力构建一些自动化的 CICD 流程,避免过多手动操作,节省一些运维的成本。在这些 CICD 流程中经常需要引入通知审批的环节,比如说项目经理是否同意把开发分支的代码可以合并到主分支。刚才提到的 SaaS 平台或者开源平台多为国外的产品,所以更多以电子邮件通知为主,而对国内很多企业,特别是以软件开发为主要业务的公司来说,电子邮件并不是效率最高通讯手段,他们很多使用效率更高的办公 APP,比如飞书,企业微信等等,然而对于这类软件,那些 Git 平台并没有提供支持。本文以一个场景为例,展示了如何使用亚马逊云科技的 Serverless 服务,整合 Git 平台和国内办公 APP,完成审批流的功能。
本文模拟了软件开发团队选择 GitOps 平台作为持续交付工具的前提下,使用 Gitlab 来管理软件新版本发布的场景,并提供了架构建议和关键部分的代码。新版本发布流程:当工程师在 Gitlab 上提交了一个 Merge request 的时候,审批人可以收到一个飞书审批消息,同时工程师也会收到一个飞书消息通知。
当审批人在飞书上做出了审批(批准或者拒绝)后,Gitlab 仓库上的 Merge request 也会做出相应处理,批准之后 Merge request 会变为 approved 状态,并做出 merge 的动作,可以触发下面的 cd 流程;拒绝之后,Merge request 会被关闭。同时工程师也会收到消息通知。
基于以上用户场景,这边设计出了一个时序图,把各方的动作和整体流程梳理一下:
整体架构
我们可以把整个流程分成两个部分,第一个部分,叫做 Gitlab 侧架构,由工程师提交 Merge request 触发,一直到发送审批者和工程师收到待审批的飞书消息通知结束;第二个部分,叫做飞书侧架构,这个部分起始于审批者批准/拒绝飞书消息,一直到动作反馈会 Gitlab 并发送消息通知结束。下面会对这两个部分分别进行介绍。
Gitlab 侧架构
架构图
AWS 服务介绍
Amazon API Gateway – 是一项 AWS 服务,用于创建、发布、维护、监控和保护任意规模的 REST、HTTP 和 WebSocket API。这里我们使用 Amazon API Gateway 创建了一个 REST API。
AWS Lambda – 是一项计算服务,可使您无需预配置或管理服务器即可运行代码。我们的示例代码使用 python 编写,版本为 3.11。
Amazon VPC – 您可以在自己定义的逻辑隔离的虚拟网络中启动 AWS 资源。
Subnet – 是您的 VPC 内的 IP 地址范围。您可以在特定子网中创建 AWS 资源(例如 EC2 实例)。
Internet Gateway – 网关是一种横向扩展、冗余且高度可用的 VPC 组件,支持在 VPC 和 Internet 之间进行通信。它支持 IPv4 和 IPv6 流量。它不会对您的网络流量造成可用性风险或带宽限制。
NAT Gateway – 是一种网络地址转换 (NAT) 服务。您可以使用 NAT 网关,以便私有子网中的实例可以连接到 VPC 外部的服务,但外部服务无法启动与这些实例的连接。
Amazon RDS – 是一种 Web 服务,可让用户更轻松地在云中设置、操作和扩展关系数据库。我们这里使用的是 Aurora MySQL 数据库,您可以按照您的喜好或者公司要求选择适合的数据库产品。
RDS Proxy – 您可以允许您的应用程序池化和共享数据库连接,以提高其扩展能力。RDS Proxy 通过在保留应用程序连接的同时自动连接到备用数据库实例,使应用程序能够更好地抵御数据库故障。使用 RDS Proxy 还使您能够为数据库强制执行 AWS Identity and Access Management (IAM) 身份验证,并将凭证安全地存储在 AWS Secrets Manager。
AWS IAM – 是一项 Web 服务,用于安全地控制对 AWS 服务的访问。借助 IAM,您可以集中管理用户、安全凭证(如访问密钥),以及控制用户和应用程序可以访问哪些 AWS 资源的权限。
Amazon CloudWatch – 提供可靠、可扩展且灵活的监控解决方案,使您能够在几分钟内开始使用。您不再需要设置、管理和扩展监控系统和基础设施了。
AWS Secrets Manager – 帮助您安全地加密、存储和检索数据库和其他服务的凭证。您可以在需要时调用安全的 Secrets Manager 来检索凭证,而不是在应用程序中对凭证进行硬编码。
架构介绍
- 当一个 Merge request 发生时,Gitlab webhook 被触发,会有一个 post 请求发送到 API Gateway。请求的 body 请见示例代码 a。
- API gateway 会使用 Lambda authorizer 验证请求并把请求发送到位于 VPC 私有子网里的 Lambda function (gitlab-hook-function)。请见示例代码 b。
- gitlab-hook-function 会把消息持久化在 Aurora MySQL 里面。Lambda function 通过 RDS Proxy 来连接 RDS 数据库,这样就不需要自己管理 connection pool,一切都可以通过 RDS proxy 管理,同时也不需要从 secret manager 获取 RDS 数据库用户名密码来连接数据库,只需要有 RDS proxy 的 connection role 就可以访问数据库。
- gitlab-hook-function 最后会调用飞书的 API,向审批人和通知人发送消息。处于私有子网的 Lambda 需要通过位于公有子网的 NAT gateway 获取公网 IP,然后通过 VPC 上的 Internet Gateway 来连接飞书 API。请见示例代码 c。
示例代码
- a. gitlab webhook 请求 body (其中我们会选择标红字段作为飞书消息的内容)
- b. 验证 gitlab 请求的 Lambda authorizer
来自 gitlab 的 webhook 会带有一个专属的 header:X-Gitlab-Token,可以通过这个 token 来验证请求真实性。 - c. 调用飞书 API
首先获取飞书的 access token使用 access token 调用发送消息的接口
飞书侧架构
架构图
架构介绍
- 当用户和卡片消息进行交互时,飞书会把交互事件通过 post 请求发送给 API gateway,在我们的 PoC 中,卡片交互事件就是审批者点击了 Merge request 审批卡片上的“通过”或者“拒绝”的按钮。
- API gateway 会把请求发送到位于 VPC 私有子网里的 Lambda function (feishu-hook-function)。
- feishu-hook-function 会首先验证消息真伪,把消息存入 RDS 数据库,并且返回更新的飞书消息(对于审批者)。更新的消息会把原本的审批卡片更新成为通知卡片消息,这样审批者就不能反复点击原本审批卡片上的按钮。请见示例代码 a。
- feishu-hook-function 还会异步调用 VPC 私有子网里面的 gitlab-merge-function。这里使用异步调用主要是因为飞书的事件调用需要在 3 秒内返回结果。请见示例代码 b。
- gitlab-merge-function 会根据审批结果调用 Gitlab 的 API,如果通过,则会调用 approve merge request 接口,然后调用 merge 接口;如果拒绝,则会调用 update 接口把 request 关闭。请见示例代码 c。
- gitlab-merge-function 还会获取飞书的 token,并且发送通知消息给通知者。
示例代码
- a. 验证飞书消息
- b. 使用 boto3 异步调用 Lambda 函数
- c. 调用 gitlab 接口 approve request,do merge,close request
准备工作
Gitlab 侧准备工作
GItlab 的代码 repositary 需要开启 webhook,填写 API gateway 的 URL,在 Trigger 选项中选择 Merge request events:
飞书开放者平台应用创建
- 登陆飞书开放者平台(https://open.feishu.cn/?lang=zh-CN)
- 创建企业自建应用
此步骤结束后,执行部署文档部署 AWS 端服务。
测试
- 为自己监控的项目创建一个分支,在分支上提交一些代码,使用 Gitlab console 或者 CLI 创建一个 Merge request 到主分支。
- 这是审批者的飞书上应该收到消息,消息上可以看到一些代码提交的信息。
- 审批者在消息上点击“通过”。
- 这个 Merge request 会自动被 approve 并且自动执行 merge 操作。
- 如果审批者在消息上点击“拒绝”。
- 这个 Merge request 会被关闭。
总结
本文介绍了如何使用亚马逊云科技的无服务器技术实现从 Gitlab 的 Merge request 事件触发飞书消息,然后从飞书事件触发 Gitlab merge 的流程。通过此架构,可以实现对 Gitlab 不同分支,不同项目,不同事件的监测;同时也可以把 git 源替换成 Github;后面结合其他即时通讯平台的接口,也可以实现其他平台的通知以及审批(比如企业微信,叮叮等)。