从 Terraform 切换到 CloudFormation - 并感到后悔

对于不需要摆弄鼠标的系统来说,以可重复的文本格式将基础设施表示为代码是一种简单的最佳实践。 这种做法有一个名字—— 基础架构即代码,到目前为止有两种流行的工具可以实现它,特别是在 AWS 中: Terraform и 云形成.

从 Terraform 切换到 CloudFormation - 并感到后悔
Terraform 和 CloudFormation 的经验比较

来之前 Twitch (AKA 小亚马逊) 我工作 在一次启动中 并使用 Terraform 三年了。 在新的地方,我也全力使用 Terraform,然后公司推动了向 Amazon 的一切过渡,包括 CloudFormation。 我努力为这两种工具开发最佳实践,并在非常复杂的组织范围内的工作流程中使用这两种工具。 后来,在深思熟虑地权衡从 Terraform 迁移到 CloudFormation 的影响后,我确信 Terraform 可能是该组织的最佳选择。

Terraform Ужасный

测试版软件

Terraform 甚至还没有发布 1.0 版本,这是不使用它的一个很好的理由。 自从我第一次亲自尝试以来,它已经改变了很多,但那时 terraform apply 经常在几次更新后或仅在使用几年后就出现故障。 我会说“现在一切都不同了”,但是……每个人似乎都这么说,不是吗? 有些更改与以前的版本不兼容,尽管它们是合适的,甚至感觉资源存储的语法和抽象现在正是我们所需要的。 该仪器似乎真的变得更好了,但是...... :-0

另一方面,AWS在保持向后兼容性方面做得很好。 这可能是因为他们的服务通常在组织内经过彻底测试,然后才重命名并发布。 因此,“他们努力尝试”是轻描淡写的。 对于像 AWS 这样多样化且复杂的系统,保持 API 的向后兼容性非常困难。 任何必须维护如此广泛使用的公共 API 的人都应该明白多年来这样做是多么困难。 但在我的记忆中,CloudFormation 的行为多年来从未改变过。

见见腿……这是一颗子弹

据我所知,删除资源 局外人 您的 CF 堆栈中的 CloudFormation 堆栈是不可能的。 Terraform 也是如此。 它允许您将现有资源导入堆栈中。 功能可以说是令人惊叹,但能力越大,责任越大。 您只需将资源添加到堆栈中,并且在使用堆栈时,无法删除或更改该资源。 有一天,事与愿违。 有一天,在 Twitch 上,有人无意中将别人的 AWS 安全组导入到自己的 Terraform 堆栈中,而没有造成任何恶作剧。 我输入了几个命令,然后...安全组(以及传入流量)消失了。

地形伟大

从不完整状态恢复

有时,CloudFormation 无法完全从一种状态转换到另一种状态。 同时,他也会尝试回到之前的状态。 遗憾的是,这并不总是可行。 调试后来发生的事情可能会非常可怕 - 你永远不知道 CloudFormation 是否会因为它被黑客攻击而感到高兴 - 即使只是修复它。 是否有可能回到之前的状态,他真的不知道如何确定,并且默认挂起几个小时等待奇迹。

另一方面,Terraform 倾向于更优雅地从失败的转换中恢复,并提供高级调试工具。

更清晰地更改文档状态

“好吧,负载均衡器,你要改变了。 但如何呢?”

—обеспокоенный инженер, готовый нажать кнопку «принять».

有时我需要对 CloudFormation 堆栈中的负载均衡器进行一些操作,例如添加端口号或更改安全组。 ClouFormation 显示变化的效果很差。 我如坐针毡般地仔细检查了 yaml 文件十次,以确保我没有删除任何必要的内容,也没有添加任何不必要的内容。

Terraform 在这方面要透明得多。 有时他甚至太透明了(读作:烦人)。 幸运的是,最新版本改进了更改的显示,以便您现在可以准确地看到正在更改的内容。

灵活性

向后编写软件。

说白了,长寿命软件最重要的特性就是适应变化的能力。 向后编写任何软件。 我最常犯的错误是采用“简单”服务,然后开始将所有内容塞入单个 CloudFormation 或 Terraform 堆栈中。 当然,几个月后我发现我理解错了,而且服务其实并不简单! 现在我需要以某种方式将大堆栈分解成小组件。 当您使用 CloudFormation 时,这只能通过首先重新创建现有堆栈来完成,而我不会对我的数据库执行此操作。 另一方面,Terraform 使得剖析堆栈并将其分解为更容易理解的较小部分成为可能。

git 中的模块

跨多个堆栈共享 Terraform 代码比共享 CloudFormation 代码容易得多。 使用 Terraform,您可以将代码放入 git 存储库中并使用语义版本控制来访问它。 任何有权访问此存储库的人都可以重用共享代码。 CloudFormation 的等价物是 S3,但它没有相同的优点,而且我们根本没有理由放弃 git 而选择 S3。

组织不断发展,共享通用堆栈的能力达到了关键水平。 Terraform 使这一切变得简单和自然,而 CloudFormation 会让你在获得这样的东西之前先经历一些困难。

操作即代码

«Заскриптуем и ладно».

——发明 Terraform 自行车 3 年前的一名工程师。

当谈到软件开发时,Go 或 Java 程序不仅仅是代码。

从 Terraform 切换到 CloudFormation - 并感到后悔
代码即代码

还有它运行的基础设施。

从 Terraform 切换到 CloudFormation - 并感到后悔
基础架构即代码

但她是哪里人? 如何监控呢? 你的代码在哪里? 开发者需要访问权限吗?

从 Terraform 切换到 CloudFormation - 并感到后悔
Operations as Code

作为一名软件开发人员并不仅仅意味着编写代码。

AWS 并不是唯一的提供商:您可能还使用其他提供商。 SignalFx、PagerDuty 或 Github。 也许您有一个用于 CI/CD 的内部 Jenkins 服务器或用于监控的内部 Grafana 仪表板。 选择基础设施作为代码有不同的原因,但每一个对于与软件相关的一切都同样重要。

当我在 Twitch 工作时,我们加速了 Amazon 混合嵌入式和 AWS 系统内的服务。 我们生产并支持许多微服务,增加了运营成本。 讨论是这样的:

  • Я:该死,超频一个微服务需要很多手势。 我将不得不使用这个垃圾来创建一个 AWS 帐户(我们在 微服务),然后这个用于设置警报,这个用于代码存储库,这个用于电子邮件列表,然后这个......
  • 带领:让我们编写脚本吧,好吧。
  • Я:好的,但是剧本本身会改变。 我们需要一种方法来检查所有这些内置的亚马逊小玩意是否都是最新的。
  • 带领: 听起来不错。 我们将为此编写一个脚本。
  • Я: 伟大的! 并且脚本可能仍然需要设置参数。 他会接受他们吗?
  • 带领: 让他去哪儿就去哪儿!
  • Я:进程可能会改变并且向后兼容性将会丢失。 需要某种语义版本控制。
  • 带领: 好想法!
  • Я:可以在用户界面内手动更改工具。 我们需要一种方法来检查和解决这个问题。

…3年后:

  • 带领:我们得到了地形。

这个故事的寓意是:即使你 по уши во всем amazon’овском,您仍在使用不是来自 AWS 的东西,并且这些服务的状态使用配置语言来保持该状态同步。

CloudFormation lambda 与 git 模块 terraform

lambda 是 CloudFormation 针对自定义逻辑问题的解决方案。 使用 lambda 你可以 创建宏 или 用户资源。 这种方法引入了 Terraform 的 git 模块语义版本控制中不存在的额外复杂性。 对我来说,最紧迫的问题是管理所有这些用户 lambda(这些是数十个 AWS 账户)的权限。 另一个重要问题是“先有鸡还是先有蛋?”问题:它与 lambda 代码有关。 这个功能本身就是基础设施和代码,它本身就需要监控和更新。 棺材上的最后一颗钉子是语义更新 lambda 代码更改的困难; 我们还必须确保没有直接命令的堆栈操作在运行之间不会改变。

我记得有一次我想使用经典的负载均衡器为 Elastic Beanstalk 环境创建金丝雀部署。 最简单的方法是在生产环境旁边对 EB 进行第二次部署,更进一步:将自动扩展金丝雀部署组与部署 LB 合并到生产环境中。 由于 Terraform 使用 ASG beantalk 作为结论,这将需要 Terraform 中额外的 4 行代码。 当我询问 CloudFormation 中是否有类似的解决方案时,他们向我指出了一个完整的 git 存储库,其中包含部署管道和所有内容,这一切都是为了可怜的 4 行 Terraform 代码可以做的事情。

它可以更好地检测漂移

确保现实符合预期。

漂移检测 是一个非常强大的操作代码功能,因为它有助于确保现实符合预期。 它可用于 CloudFormation 和 Terraform。 但随着生产堆栈的增长,在 CloudFormation 中搜索漂移会产生越来越多的错误检测。

借助 Terraform,您可以拥有更高级的生命周期挂钩来进行漂移检测。 例如,您输入命令 忽略更改 如果您想要忽略对特定任务定义的更改而不忽略对整个 ECS 部署的更改,请直接在 ECS 任务定义中执行此操作。

CDK 和 CloudFormation 的未来

CloudFormation 很难在跨基础架构的大规模范围内进行管理。 其中许多困难已被认识到,并且该工具需要诸如 aws-cdk,一个用于在代码中定义云基础设施并通过 AWS CloudFormation 运行它的框架。 看看 aws-cdk 的未来将会很有趣,但它将很难与 Terraform 的其他优势竞争; 为了使 CloudFormation 保持最新状态,需要进行全局更改。

Чтобы Terraform не разочаровал

这是“基础设施作为代码”,而不是“作为文本”。

我对 Terraform 的第一印象相当糟糕。 我想我只是不理解这种方法。 几乎所有工程师都会不自觉地将其视为需要转换为所需基础设施的文本格式。 不要这样做。

优秀软件开发的真理也适用于 Terraform。

我看到许多用于创建良好代码的实践在 Terraform 中被忽略了。 你已经学习多年才能成为一名优秀的程序员。 不要仅仅因为您正在使用 Terraform 就放弃这种体验。 优秀软件开发的真理也适用于 Terraform。

代码怎么能不被记录呢?

我见过巨大的 Terraform 堆栈,但完全没有文档。 如何在完全没有文档的情况下在页面中编写代码? 添加解释您的文档 Terraform(强调“代码”一词),为什么本节如此重要,以及您做什么。

Как можно разворачивать сервисы, которые некогда были одной большой функцией main()?

Мне встречались очень сложные стеки Terraform, представленные в виде единого модуля. Почему мы так не разворачиваем ПО? Зачем дробим крупные функции на более мелкие? Те же ответы справедливы и для Terraform. Если модуль у вас слишком велик — надо его разбить на модули поменьше.

你们公司不使用图书馆吗?

Я видел, как инженеры, раскручивая новый проект при помощи Terraform, тупо копи-пейстили громадные куски из других проектов в свои собственные, а потом ковыряли их, пока не начинало работать. Вот вы у себя в компании стали бы работать так с «боевым» кодом? Мы же не просто так пользуемся библиотеками. Да, 并非一切都必须是图书馆, 但是原则上如果没有共享库我们会怎样呢?!

Разве вы не пользуетесь PEP8 или gofmt?

大多数语言都有一个标准的、可接受的格式方案。 在 Python 中,这是 PEP8。 在 Go 中 - gofmt。 Terraform 有自己的: terraform fmt。 为了您的健康,请享受它!

你会在不懂 JavaScript 的情况下使用 React 吗?

Terraform 模块可以简化您创建的复杂基础设施的某些部分,但这并不意味着您根本无法对其进行修改。 想要在不了解资源的情况下正确使用 Terraform? 你注定了:时间会过去,你永远无法掌握 Terraform。

您使用单例还是依赖注入进行编码?

依赖注入是公认的软件开发最佳实践,并且比单例更受青睐。 这在 Terraform 中有何用处? 我见过依赖于远程状态的 Terraform 模块。 不要编写检索远程状态的模块,而是编写接受参数的模块。 然后将这些参数传递给模块。

您的图书馆在十件事上做得很好还是在一件事情上做得很好?

效果最好的图书馆是那些专注于自己擅长的一项任务的图书馆。 不要编写试图同时完成所有事情的大型 Terraform 模块,而是构建其中只做好一件事的部分。 然后根据需要将它们组合起来。

如何在不向后兼容的情况下对库进行更改?

常见的 Terraform 模块与常规库一样,需要以某种方式向用户传达更改,而不需要向后兼容。 当这些更改发生在库中时,这很烦人,并且当 Terraform 模块中进行非向后兼容的更改时,这也同样令人烦人。 使用 Terraform 模块时建议使用 git tag 和 semver。

您的生产服务是在笔记本电脑上还是在数据中心中运行?

Hashicorp 有类似的工具 terraform cloud 运行你的地形。 这些集中式服务可以轻松管理、审核和批准 terraform 更改。

Разве вы не пишете тесты?

Инженеры признают, что код нужно тестировать, но сами при этом часто забивают на проверки, работая с Terraform. Для инфраструктуры это чревато коварными моментами. Я советую «тестировать» или «создавать примеры» стеков с использованием модулей, которые можно корректно задеплоить для проверки во время CI/CD.

Terraform 和微服务

微服务公司的生死取决于新微服务工作堆栈的速度、创新和颠覆。

Самый распространенный негативный момент, связанный с микросервисными архитектурами и от которого никак не избавятся, связан с работой, а не с кодом. Если воспринимать Terraform, лишь как способ автоматизировать только инфраструктурную сторону микросервисной архитектуры, то вы лишаете себя подлинных преимуществ этой системы. Сейчас уже 一切都像代码.

来源: habr.com

添加评论