作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
法布里斯·特里布瓦的头像

法布里斯Triboix

Fabrice是aws认证的云架构师 & 拥有20多年在Topps、思科、Samsung和Alcatel等公司工作经验的开发者.

以前在

思科
分享

如果你像我一样,在互联网上搜索以帮助你在云Formation和 起程拓殖 作为下一个基础设施即代码(IaC)工具,而没有找到明确的答案, 我分担了你很长一段时间的痛苦. 现在, 我对这两种工具都有丰富的经验,我可以做出明智的决定,选择使用哪一个.

博士TL;

对于您在AWS上的IaC项目,请选择云Formation,因为:

  1. 云Formation区分了代码(i.e.,模板)和代码的实例化(i.e.栈). 在起程拓殖中,没有这样的区别. 下一节将详细介绍这一点.
  2. 起程拓殖不能很好地处理基本的依赖关系管理. 后面的部分将详细介绍这一点.

区分代码和实例化

云Formation和起程拓殖之间的一个区别是每个服务中的代码和实例化如何相互关联.

云Formation有a的概念 堆栈,它是模板的实例化. 可以实例化相同的模板 无限 通过给定帐户中的给定客户,跨帐户或不同客户.

起程拓殖 没有这样的概念,并且需要代码与其实例化之间的一对一关系. 这类似于为您想要运行的每个服务器复制web服务器的源代码, 或者在每次需要运行应用程序而不是运行编译后的版本时复制代码.

这一点在简单设置的情况下是相当微不足道的, 但它很快就会成为大中型企业的一大痛点. 在起程拓殖, 每次需要从现有代码中启动一个新堆栈时, 您需要复制代码. 复制/粘贴脚本文件是一种很容易破坏自己的方法,也会破坏你不想碰的资源.

起程拓殖实际上并没有 像云Formation, 这清楚地表明,起程拓殖已经从头开始构建,以便在代码和它管理的资源之间实现一对一的匹配. 这一点后来被部分地纠正了 环境 (后来被重新命名为“工作区”), 但是使用它们的方式使得部署到不需要的环境非常容易. 这是因为你必须逃跑 地形工作区选择 部署前, 忘记这一步将部署到之前选择的工作空间, 哪个是你想要的,哪个不是.

在实践中, 使用起程拓殖模块确实减轻了这个问题, 但即使在最好的情况下, 您将需要大量的样板代码. 事实上, 这个问题非常严重,以至于人们需要在起程拓殖周围创建一个包装工具来解决这个问题: Terragrunt.

状态管理与权限

云Formation和起程拓殖之间的另一个重要区别是它们各自管理状态和权限的方式.

云Formation为您管理堆栈状态,并且不给您任何选项. 但是在我的经验中,云Formation堆栈状态是稳定的. 也, 云Formation允许权限较低的用户管理堆栈,而无需拥有堆栈本身所需的所有必要权限. 这是因为云Formation可以从附加到堆栈的服务角色获得权限,而不是从运行堆栈操作的用户获得权限.

起程拓殖需要您为它提供一些后端来管理状态. 默认是一个本地文件,这是完全不令人满意的,给出:

  1. 状态文件的健壮性完全与存储它的机器的健壮性相关联.
  2. 这几乎让团队合作变得不可能.

因此,您需要一个健壮的共享状态, 在AWS上通常是通过使用S3桶来存储状态文件来实现的, 附带一个DynamoDB表来处理并发性.

这意味着您需要为要实例化的每个堆栈手动创建S3桶和DynamoDB表, 还要手动管理这两个对象的权限,以限制权限较低的用户访问他们不应该访问的数据. 如果你只有几摞的话, 那不会有太大的问题, 但如果你有20堆东西要处理, 这确实变得非常麻烦.

顺便说一下, 使用起程拓殖工作区时, 每个工作区不可能有一个DynamoDB表. 这意味着,如果您希望使用具有最小权限的IAM用户来执行部署, 该用户将能够摆弄所有工作区的锁,因为DynamoDB权限没有细粒度到项目级别.

依赖关系管理

在这一点上,云Formation和起程拓殖都可能有点棘手. 如果修改逻辑ID (i.e., 资源的名称, 两者都认为必须销毁旧资源并创建新资源. 因此,在任何一种工具中更改资源的逻辑ID通常都不是一个好主意, 特别是对于云Formation中的嵌套堆栈.

如第一节所述,起程拓殖不处理基本依赖项. 不幸的是,起程拓殖的开发者并没有给予 长期存在的问题 很多关注,尽管很明显 缺乏变通办法.

考虑到适当的依赖管理对于IaC工具是绝对关键的, 一旦涉及到关键业务操作,起程拓殖中的这些问题就会使其适用性受到质疑, 例如部署到生产环境. 云Formation给人更专业的感觉, AWS一直非常注意确保为客户提供生产级工具. 这些年来,我一直在使用云Formation, 我从来没有遇到过依赖管理的问题.

云Formation允许堆栈导出它的一些输出变量, 然后可以被其他堆栈重用. 说实话, 这个功能是有限的, 因为您将无法在每个区域实例化多个堆栈. 这是因为您不能导出两个具有相同名称的变量, 导出的变量没有名称空间.

terrraform没有提供这样的设施,所以你就没有那么理想的选择了. 起程拓殖允许您导入另一个堆栈的状态, 但这样就可以访问堆栈中的所有信息, 包括存储在国家的许多秘密. 另外, 堆栈可以以JSON文件的形式导出一些变量,存储在S3桶中, 但是再一次, 这个选项比较麻烦:您必须决定使用哪个S3存储桶,并赋予它适当的权限, 并且自己编写所有的管道代码,包括编写器和读取器.

起程拓殖的一个优点是它有数据源. 因此,起程拓殖可以查询不受起程拓殖管理的资源. 然而, 在实践中, 当您想要编写泛型模板时,这一点没有什么关系,因为这样您就不会对目标帐户做任何假设. 在云Formation中,等效的方法是添加更多的模板参数, which thus involves repetition and potential for errors; 然而, 根据我的经验, 这从来都不是问题.

回到起程拓殖的依赖管理问题, 另一个例子是,当你试图更新负载平衡器的设置时,你会得到一个错误,并得到以下内容:

错误:删除目标组错误:ResourceInUse:目标组'arn:aws:elasticloadbalancing:us-east:723207552760:targetgroup/strategy-api-default-us-east-1/14a4277881e84797'当前正在被侦听器或规则使用

    状态码:400,请求id: 833d8475-f702-4e01-aa3a-d6fa0a141905

预期的行为是,起程拓殖检测到目标组是未被删除的其他资源的依赖项, 因此, 它不应该试图删除它——但也不应该抛出错误.

操作

虽然起程拓殖是一个命令行工具, 很明显,它希望一个人来管理它, 因为它具有很强的互动性. 可以在批处理模式下运行它.e.(从脚本),但这需要一些额外的命令行参数. 事实上,terrraform已经被开发为默认由人类运行是相当令人费解的, 考虑到IaC工具的目的是自动化.

起程拓殖是 难以调试. 错误消息通常是非常基本的,不允许您了解哪里出了问题, 在这种情况下,你必须运行起程拓殖 TF_LOG =调试,它产生了大量的输出来进行拖网搜索. 使这, 起程拓殖对AWS的API调用有时会失败, 但失败不是起程拓殖的问题. 与此形成鲜明对比的是, 云Formation提供了相当清晰的错误消息,并提供了足够的详细信息,使您能够了解问题所在.

一个示例起程拓殖错误消息:

Error:读取S3桶错误Public Access Block: NoSuchBucket:指定的桶不存在

    状态码:404, 请求id: 19AAE641F0B4AC7F, 主机id: rZkgloKqxP2/a2F6BYrrkcJthba/FQM/DaZnj8EQq/5FactUctdREq8L3Xb6DgJmyKcpImipv4s=

上面的错误消息显示了一个清晰的错误消息,实际上并没有反映出潜在的问题(在本例中是权限问题)。.

此错误信息还显示了起程拓殖有时如何将自己绘制到角落. 例如,如果您创建了S3桶和 aws_s3_bucket_public_access_block 存储桶上的资源, 如果出于某种原因,你在terrform代码中做了一些改变,破坏了那个桶e.g., 在上面描述的“更改意味着删除和创建”的问题中,terraform将在加载 aws_s3_bucket_public_access_block 但不断失败与上述错误. 起程拓殖的正确行为应该是替换或删除 aws_s3_bucket_public_access_block 适当的.

最后,您不能将云Formation helper脚本与起程拓殖一起使用. 这可能是一个烦恼, 特别是如果你想用cfn信号, 它告诉云Formation, EC2实例已经完成了初始化,并准备为请求提供服务.

语法、团体和回滚

语法方面,与cloudformation相比,起程拓殖确实有一个很好的优势——它支持循环. 但根据我自己的经验,这个功能可能会有点危险. 通常, a loop would be used to create a number of identical resources; 然而, 当您想用不同的计数更新堆栈时, 您可能需要链接旧资源和新资源(例如, 使用 zipmap () 将两个数组的值组合(现在恰好大小不同因为一个数组的大小是旧循环的大小而另一个数组的大小是新循环的大小). 如果没有循环,这样的问题确实会发生, 但是没有循环, 对于编写脚本的人来说,这个问题要明显得多. 在这种情况下使用循环会混淆问题.

起程拓殖的语法和云Formation的语法哪个更好主要是一个偏好问题. 云Formation最初只支持JSON,但是JSON模板很难阅读. 幸运的是,云Formation还支持YAML,它更容易阅读并允许注释. 不过,云Formation的语法往往相当冗长.

起程拓殖的语法使用HCL,这是JSON的一种衍生,非常特殊. 起程拓殖提供了比云Formation更多的功能,而且它们通常更容易理解. 所以可以说,在这一点上,起程拓殖确实有一点优势.

起程拓殖的另一个优点是其易于获得的社区维护模块集, 这确实简化了模板的编写. 一个问题可能是,这些模块可能不够安全,无法满足组织的需求. 所以对于需要高度安全的组织来说, 回顾这些模块(以及以后的版本)可能是必要的.

一般来说,起程拓殖模块比云Formation嵌套堆栈灵活得多. 云Formation嵌套堆栈倾向于隐藏它下面的所有内容. 从嵌套堆栈中, 更新操作将显示嵌套堆栈将被更新,但不会详细显示嵌套堆栈内部将发生什么.

最后一点, 哪一个是有争议的, 云Formation是否试图回滚失败的部署. 这是一个非常有趣的功能,但不幸的是,它可能非常长(例如, 云Formation可能需要三个小时的时间来判断到弹性容器服务的部署是否失败). 相反,在失败的情况下,起程拓殖就会停在原地. 回滚特性是好是坏是有争议的, 但我已经开始欣赏这样一个事实,即当更长时间的等待恰好是可以接受的权衡时,堆栈尽可能地保持在工作状态.

在捍卫地形vs. 云Formation

起程拓殖确实比云Formation有优势. 在我看来,最重要的一点是,当应用更新时,起程拓殖会显示给你 所有 您将要进行的更改,包括向下钻取到它正在使用的所有模块. 相比之下, 云Formation, 使用嵌套堆栈时, 只显示嵌套堆栈需要更新, 但没有提供深入到细节的方法. 这可能令人沮丧, 在点击“go”按钮之前,了解这类信息是非常重要的.

云Formation和起程拓殖都支持扩展. 在云Formation, 通过使用您自己创建的AWS Lambda函数作为后端,可以管理所谓的“自定义资源”. 对于起程拓殖,扩展更容易编写并成为代码的一部分. 所以在这种情况下,起程拓殖有一个优势.

起程拓殖可以处理许多云供应商. 这使得起程拓殖能够在多个云平台之间统一给定的部署. 例如,假设您在AWS和Google 云 Platform (GCP)之间有一个单一的工作负载分布。. 正常情况下, 工作负载的AWS部分将使用云Formation进行部署, GCP部分使用GCP的云部署管理器. 与起程拓殖, 相反,您可以使用单个脚本在各自的云平台中部署和管理这两个堆栈. 通过这种方式,您只需要部署一个堆栈而不是两个.

起程拓殖vs .的非参数. 云Formation

有相当多的非论点继续在互联网上流传. 最大的问题是,因为起程拓殖是多云的, 您可以使用一个工具来部署所有项目, 无论在哪个云平台上完成. 从技术上讲, 这是真的, 但这并不是看起来那么大的优势, 尤其是在管理典型的单云项目时. 事实上,在(例如)云Formation中声明的资源和在起程拓殖脚本中声明的相同资源之间几乎是一对一的对应关系. 因为无论哪种方式,您都必须了解特定于云的资源的详细信息, 区别在于语法, 管理部署中最大的痛点是什么.

一些人认为,通过使用起程拓殖,可以避免供应商锁定. 这个论点在某种意义上并不成立,通过使用起程拓殖, 你被HashiCorp (起程拓殖的创建者)锁定了, 就像使用云Formation一样, 您被AWS锁定了, 其他云平台也是如此.

起程拓殖模块更容易使用的事实对我来说不那么重要. 首先, 我相信,AWS有意避免为基于社区的云Formation模板托管单一存储库,因为它意识到对用户制造的安全漏洞和违反各种合规程序的责任.

在更私人的层面上, 我完全理解在软件开发中使用库的好处, 因为这些库可以很容易地运行到数万行代码中. 以IaC为例, 然而, 代码的大小通常要小得多, 这样的模块通常有几十行长. 使用复制/粘贴实际上并不是一个坏主意,因为它避免了维护兼容性和将安全性委托给不认识的人的问题.

许多开发人员和DevOps工程师不赞成使用复制/粘贴, 这背后有很好的理由. 然而, 我的观点是,对代码片段使用复制/粘贴可以让您轻松地根据自己的需要进行调整, 没有必要把它变成一个库,也没有必要花很多时间把它变成通用的. 维护这些代码片段的痛苦通常很低, 除非你的代码在, 说, 十几个或更多的模板. 在这种情况下, 占用代码并将其用作嵌套堆栈是有意义的, 在执行更新操作时,不重复操作的好处可能比无法看到嵌套堆栈中将要更新的内容的烦恼更大.

云Formation vs. 起程拓殖的结论

与云Formation, AWS希望为其客户提供一个坚如磐石的工具,它可以在任何时候都按预期工作. 起程拓殖的团队也是如此, 当然——但这似乎是他们的工具的一个关键方面, 依赖关系管理, 不幸的是,这不是一个优先事项.

起程拓殖可能在您的项目中占有一席之地, 特别是如果你有一个多云架构, 在这种情况下,起程拓殖脚本是统一管理您正在使用的各种云供应商的资源的一种方法. 但是在这种情况下,您仍然可以通过只使用起程拓殖来管理已经使用各自的云特定IaC工具实现的堆栈来避免起程拓殖的缺点.

整体感觉:地形vs. 云Formation就是云Formation, 虽然不完美, 是否更专业可靠, 我绝对推荐它用于任何不是多云的项目.

了解基本知识

  • 什么是云Formation?

    云Formation是Amazon Web Services的官方基础设施即代码(IaC)软件. 云Formation自动化和编排任何AWS资源的创建、更新和删除. 此外,云Formation允许细粒度的权限,可以回滚失败的部署.

  • 云Formation的用途是什么?

    云Formation可用于自动化和编排创建, 更新, 删除AWS资源, 基于脚本. 这允许对基础结构进行文档化, 作为一组文本文件对基础架构进行版本控制和存储, 跨帐户和环境的可再现性, 以及持续部署.

  • 云Formation的主要组件是什么?

    云Formation的主要组件是:云Formation模板(定义基础架构应该是什么样子的声明性脚本), 栈(可以嵌套的云Formation模板的实例), 和StackSets(允许您跨帐户和区域管理云Formation堆栈).

  • 起程拓殖和云Formation的区别是什么?

    起程拓殖和云Formation都是基础设施即代码(IaC)工具. 云Formation由AWS开发,只管理AWS的资源. 起程拓殖是由HashiCorp开发的,可以管理各种云供应商的资源.

  • 为什么云Formation比起程拓殖更好?

    对于受限于AWS的生产工作负载,云Formation比起程拓殖更好. 主要原因是,在某些情况下, 起程拓殖不能正确处理依赖关系, 这就排除了它作为生产就绪的基础设施即代码(IaC)软件的可能性.

  • 起程拓殖是用来做什么的?

    起程拓殖是一个基础设施即代码(IaC)工具, 因此,它被用于自动创建和管理云资源. 起程拓殖的一个显著特点是它支持广泛的云平台.

  • 谁创造了起程拓殖?

    起程拓殖是由HashiCorp创建的基础设施即代码(IaC)软件. 它是用Golang语言编写的,于2014年首次发布. 起程拓殖是免费的开源软件.

  • 起程拓殖是一个DevOps工具吗?

    是的,起程拓殖是一个DevOps工具. 它是基础设施即代码(IaC)软件, 这样的软件是自动化部署策略的关键部分.

就这一主题咨询作者或专家.
预约电话
法布里斯·特里布瓦的头像
法布里斯Triboix

位于 英国伦敦

成员自 2017年9月6日

作者简介

Fabrice是aws认证的云架构师 & 拥有20多年在Topps、思科、Samsung和Alcatel等公司工作经验的开发者.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

以前在

思科

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® 社区.