我们应该使用Jenkins还是CodeBuild?这是一个永恒的问题。
一方面,Jenkins允许你在你的版本库中定义构建和管道,另一方面,Jenkins服务器是一个需要维护的猛兽。
CodeBuild和CodePipeline本质上是无服务器的Jenkins......但缺少一些关键的东西。
缺少了什么?
一些不好的东西已经消失了
- 服务器补丁
- 构建代理的数量管理
- 根据负载情况调整Jenkins服务器的规模
- 为服务器闲置时的时间付费
- Jenkins主机配置之间的随机变化
缺少一些好东西
- 一个干净的管道脚本语言
- 自动发现组织中的构建内容
- 整体的仪表盘来导航你的组织
- 构建/管道的单一图片
CodeBuild和管道FTW
尽管失去Jenkins可能会有短期的缺点,但如果你已经在使用AWS,CodeBuild的方法实在是太容易被拒绝了。唯一的转折点是,如果你已经在Jenkins中拥有巨大的不动产,可能不值得迁移。或者,如果你有一套复杂的、相互调用的构建,那么Jenkins可能会有帮助。
最后,如果某个地方的管理员很乐意为你运行一个Jenkins农场,那么也许要走的路是50/50。
弥补差距
在我目前的任务中,我试图解决三个问题:
- 扫描我们GitHub组织的仓库,自动生成构建和管道
- 规范构建和管道的工作方式,并进行适当的复制和粘贴
- 因此,使用声明式管道脚本进行部署
我已经用自己的工具解决了这个问题,下面我大概分享一下我是如何做到的。
适量的复制和粘贴
我们倾向于发现我们的Jenkinsfile 是大量复制和粘贴的来源,也许这是好的。一个基本的buildspec.yaml ,为每一个分支吐出构建,不会有那么多的变化,但却几乎无法参考。
如果不同的 repo 构建的关键部分是共享的资产,你就会得到奇怪的跨项目的依赖性,这其实并没有什么好处。
什么是标准的构建过程?
有很多方法可以使CodeBuild和CodePipeline成熟。我们的流程是:
- CodeBuild由GitHub的每个PUSH请求触发,进行构建。
- 如果推送到
main,那么CodeBuild规范就会将构建的资产打包,并将其放入S3供CodePipeline使用。 - CodePipeline观察S3并在有新包时运行。
尽管CodePipeline可以由GitHub触发,但我们并不希望每个分支都有部署。我们希望每个分支都有一个构建。
如何产生构建和管道
CodeBuild和CodePipeline可以通过Cloudformation模板创建。如果我们有某种工具可以生成一个Cloudformation模板来描述我们需要的所有构建和管道,那么我们就可以部署该模板,构建就会存在。
所以,我们创建一个扫描工具作为一个预定的lambda,扫描GitHub并输出模板。然后,让我们有一个CodePipeline作业,它消耗输出的模板,并部署它来创建各种构建。哦,让我们为预定的lambda定义构建和管道,以及在这个_超级_模板中为生成的模板定义管道。
这意味着你第一次在本地运行lambda时,它就会吐出模板来引导AWS中的整个架构。
这是很不错的。
这也意味着,如果扫描注意到一个不再存在的 repo,或者需要一个构建或管道,产生的模板将省略这些构建,导致这个过程既创建又删除模板(也更新它们)。
那么,我如何创建这样一个东西?
你如何精确地选择这样做,是一个你能制造和支持什么的问题。以下是我使用的技术栈:
- 用于Lambda的TypeScript
Octokit作为GitHub客户端yaml作为一个Java/TypeScript yaml读写器jszip来制作推送到S3的压缩文件
我的解决方案是将它要存储在S3中的模板与已经存在的模板进行比较,如果没有区别,就不重新发布。
诡异的怪癖!Ref
最后一个细节是,.yml 中的Cloudformation模板喜欢使用!Ref ,以代替某些值来引用模板的其他部分。事实证明,让这一点在一个通用的.yml 阅读器上工作是相当困难的。其他的快捷函数也是如此(在我的解决方案中没有使用)。
结论
我花了不少功夫才把它弄好,但在使用它的头几个小时里,它几乎把我所有的构建和管道都喷出来了,而且它们都能工作。我允许每个 repo 对构建和管道的细节有一些控制,如果他们想的话,但到目前为止,我很少需要它。
这个解决方案似乎可以很好地利用现有的工具。我相信它会有一些成长的痛苦,但同样,它似乎在标准和复制/粘贴模板之间取得了良好的平衡。
说白了,要获得一个构建,我只需要写一个buildspec.yaml 文件,一个构建会在几分钟内出现(除非我不耐烦,用手去触发lambda)。
要获得一个管道,我只需写一个小的自定义.yml 文件,其中包含一些参数,描述我想使用我们标准管道的哪些功能。
自定义是通过允许混入的方式实现的,我们可以在Cloudformation模板的标准部分添加一些覆盖值,所以要解释的新语法越少越好。
我可能会在以后的报告中说,这最终使生活变得艰难,但我们目前真的很享受这种方法的蜜月期。