关于开发基础结构代码的简短大师班

在今年的10月,我在HashiConf 2018大会上做了一个演讲,在那里我谈到了来自Gruntwork的同事们和我在创建和维护包含300,000行基础设施代码的库的过程中吸取的5个关键课程,供数百家公司在生产系统中使用。 在本出版物中,我将分享演示文稿中的视频和幻灯片,以及5个主要课程的简要介绍。
影片和幻灯片
简介:石器时代的DevOps
尽管该行业充满了时尚的进步词汇:Kubernetes,微服务,服务网格,不变的基础架构,大数据,数据湖等,但事实是,当您沉浸于基础架构的创建中时,您不会感到如此时尚和进步。
就个人而言,DevOps让我更加想起了这一点:




创建生产级基础架构很困难。 这是真正的压力。 而且吃很多时间。 很多时间。
它显示了实施下一个基础设施项目将花费的时间。 我们依赖于在数百家不同公司的工作过程中收集的经验数据:

课程1.制造基础结构清单
DevOps项目总是花费比您预期更长的时间。 总是 为什么这样
第一个原因是a 牛发型 。 下面是这种现象的生动例证((摘录自“聚光灯下的马尔科姆”系列)
第二个原因是,创建生产级基础结构(例如,将要放置公司的基础结构)的过程包含成千上万个小部分。 绝大多数开发人员都不知道这些细节,因此,在评估项目时,您通常会忘记许多关键(且耗时)的任务。
为避免这种情况,每次开始在基础结构的新部分上工作时,请使用以下清单:

并不是每个基础架构都需要列表中的所有元素,但是您必须自觉和明确地记录实现的元素,决定跳过的元素以及原因。
第二课。工具箱
我们列出了Gruntwork上用于创建和管理基础架构的主要工具(截至2018年):

- 地形 。 我们使用Terraform部署整个基础架构,包括网络,负载平衡子系统,数据库,用户和权限管理工具以及所有服务器。
- 打包机 。 我们使用Packer来配置和创建在服务器上运行的虚拟机的映像。
- 码头工人 我们的一些服务器形成集群,在集群中我们将应用程序作为Docker容器运行。 对于Docker集群,我们主要使用以下工具: Kubernetes , ECS和Fargate 。
所有这些工具都很有用,但这不是重点。 您需要了解一些工具还不够。 也有必要更改团队的行为。
尤其是,即使世界上最好的工具,如果他们不想使用它们或他们没有足够的时间来学习如何使用它们,也不会对您的团队有所帮助。 因此,关键结论是使用“基础架构作为代码”是一项投资,也就是说,您将需要一定的初始成本。 如果您明智地进行投资,从长远来看,您将获得丰厚的回报。
第3课。大模块是邪恶的
应用“基础架构即代码”的新手通常会在一个文件或一组整体部署的文件中定义其所有环境(开发环境,中间环境,生产环境等)的整个基础架构。 是徒劳的。
这只是此方法的一些缺点:
- 低速 如果整个基础架构都定义在一个地方,那么执行任何命令都将花费大量时间。 当地形
terraform plan
团队花了5-6分钟完成工作时,我们就遇到了公司的情况! - 安全性低 。 如果您一起管理整个基础架构,那么要更改某些内容,您需要具有访问所有内容的权限。 也就是说,几乎每个用户都应该是管理员,这也非常不方便。
- 高风险 。 如果将所有鸡蛋都放在一个篮子里,那么就会出现一个局部错误会破坏整个基础架构运行的情况。 例如,当您在开发环境中对外部应用程序进行细微更改时,单个错字或不正确的命令都可能导致生产数据库的删除。
- 很难理解 。 在一个地方放置的代码越多,一个人理解所有这些的难度就越大。 当所有这些连接在一起时,难以理解的部分将与您开玩笑。
- 很难测试 。 测试基础架构代码很困难; 测试大量的基础架构代码几乎是不可能的。 我们待会儿会再谈这个。
- 很难分析 。 诸如地形计划之类的命令的输出变得无用,因为没有人去看数千行。 而且,代码分析变得毫无用处。
简而言之,您必须从小型,独立且可重用的复合模块中构建代码。 这既不是新闻,也不是发现。 您听到过一千遍,尽管情况略有不同:
“做一件事并做好事”-Unix哲学。
“功能的首要规则是它们应该很小。 第二条规则规定功能应该更小。” -“清理代码”
第4课。没有自动测试的基础结构代码有故障
如果您的基础结构代码没有自动测试,则无法正常工作。 您只是还不知道。 但是测试基础架构代码很困难。 您没有“本地主机”(例如,您无法在便携式计算机上部署AWS VPC虚拟私有云),也没有真正的“单元测试”(例如,您无法将Terraform代码与“外部”世界隔离开来,因为它就像时代,并旨在与外界沟通。
因此,为了正确地测试基础结构代码,通常必须将其部署在真实的环境中,运行真实的基础结构,验证代码是否有效,然后破坏它(有关此测试样式的说明:请参见Terratest,这是一个开放源代码库,其中包含用于测试Terraform代码的工具,Packer和Docker,与AWS,GCP和Kubernetes API配合使用,通过SSH在本地和远程服务器上执行Shell命令,以及其他许多功能)。 因此,在测试基础结构时,您需要稍微重新定义条件:

单元测试将部署并测试一个或多个紧密相关的相同类型的基础结构模块(例如,用于单个数据库的模块)。
集成测试将部署并测试各种类型的几个基础结构模块,以验证它们是否可以协同工作(例如,数据库模块和Web服务模块)。
端到端测试 (e2e)部署和测试整个体系结构。
请注意,该图是一个金字塔:我们有很多单元测试,更少的集成测试和很少的e2e测试。 怎么了 这取决于每种测试的持续时间:

基础结构测试需要花费大量时间,尤其是在金字塔的高层,并且,当然,您将希望在最底层找到并修复尽可能多的错误。 为此,您需要:
- 创建小型简单的独立模块(请参阅第3课),并为它们编写许多单元测试-确保它们正常工作。
- 结合这些小巧,简单且经过验证的模块,可以创建更复杂的基础架构,并通过更少的集成和E2E测试来进行测试。
第5课。发布过程
总结以上所有内容。 现在,您将按照以下方法创建和管理基础结构:
- 检查清单以了解生产级基础结构 ,并确保您的工作方向正确。
- 使用Terraform,Packer和Docker等工具将“基础结构作为代码”定义。 确保您的团队有足够的时间来学习这些工具(请参阅DevOps资源 )。
- 从小型和独立的组合模块创建代码(或使用基础结构中的标准模块作为代码库 )。
- 使用Terratest为模块准备自动化测试。
- 完成请求以包括您的更改以检查代码。
- 发行新版本的代码。
- 将新版本的代码从一个环境复制到另一个环境。
