学习Terraform相对容易。HCL配置语言非常简单,可以直接开始创建基本的资源。
然而,随着基础架构代码的复杂性、可维护性和依赖性的增加,可能会面临一些挑战。因此,制定一个有效的部署工作流对于进一步开发是至关重要的。
本文展开五种管理大规模Terraform工作流的方法,它们的优点、缺点以及解决的问题。
请注意:新版本的Terraform将采用BUSL许可证,但在1.5版本之前创建的所有内容将保持开源。OpenTofu是Terraform的一个开源版本,它扩展了Terraform现有的概念和产品。它是从Terraform 1.5.6版本派生而来的,作为HashiCorp Terraform的可行替代方案。OpenTofu保留了使Terraform在开发人员中流行的所有特性和功能,并引入了改进和增强。拥有一个真正的开源项目来支持的所有基础架构即代码(IaC)需求是非常重要的,这使得OpenTofu成为Terraform生态系统的未来。
1.本地工作开发
使用本地Terraform在同一台机器上快速部署资源是一种简便的方法,以基础设施即代码(IaC)的方式开始。这种方法要求能够访问目标提供程序并安装了Terraform二进制文件。
尽管这是使用Terraform的最简单方法之一,但它并不是最佳实践。一旦的项目扩展并有多个DevOps工程师共同参与,这种方法就会变得非常复杂。
可以使用Terraform的所有功能,例如远程状态和状态锁定,以与团队成员一起协作。如果正在使用版本控制系统进行协作,但没有进行持续集成,有一些工具可以帮助保持代码质量。
其中之一是pre-commit-terraform,它会在提交代码之前运行一组选定的工具,检查正在创建的代码。即使在有持续集成可用的情况下,这也是一种方便的方式,避免等待拉取请求状态检查结果的时间浪费。
然而,这种方法也存在一些缺点。每个操作都是手动的,需要由开发人员直接执行,这会导致一些问题。在多人共同处理同一代码库的情况下,可能会经常遇到以下场景:人员A将其更改应用于环境并执行拉取请求,同时,人员B希望部署他们的更改,但由于代码库与人员A的更改不同步而被阻止。在这种状态下应用更改将对之前部署中创建的资源造成破坏。当在较大的团队中工作时,这通常会浪费大量时间,只是等待和重新基于代码库应用更改。
另外,如果为Terraform模块编写了单元测试(建议这样做),可能知道它们需要在计算机上手动运行。每次更改配置时运行它们可能会变得乏味且耗时。如果尚未为模块编写测试,建议查看Spacelift模块测试或Terratest。
此外,使用本地部署的每个人都需要访问Terraform状态。由于Terraform状态的工作方式,这会引发安全问题。即使从外部系统(如Vault)提取敏感数据,一旦在资源中使用,它也会以明文形式存储在状态文件中。恶意行为者可以简单地运行"terraform state pull"来获取所有的秘密。
综上所述,尽管本地部署可以快速上手,但随着项目的发展和团队规模的增大,更自动化的方法将更加可取。
2.实现本地自动化
实现本地自动化意味着将Terraform工作流整合到的持续集成/持续部署(CI/CD)流程中。尽管这个过程对于不同的CI/CD工具有一些特定要求,但我们可以提供一些通用的建议。
首先,需要确保CI/CD系统具有适当的权限来执行Terraform操作。开发人员可以保持只读权限,而CI/CD系统则具有执行权限。这样,开发人员无需特权访问即可进行工作。对于私有或内部资源,应该确保已设置适当的权限,并在CI/CD系统上执行操作。
将检查、合规检查和自动化单元测试移动到拉取请求状态检查中是一个好主意。可以在CI/CD流程中配置这些步骤,并通过生成实时系统日志来提高可见性。
然而,如果的CI/CD系统并发执行作业,可能会出现竞态条件,导致拉取请求的结果不确定。例如,如果两个操作员在几秒钟内打开了不同的拉取请求,CI/CD管道可能会同时触发,导致一个拉取请求成功,而另一个失败。即使使用状态锁定(这是一个最佳实践,应该使用它),这个问题也会出现。
这个问题可以通过配置排队运行来解决,即一次只能运行一个管道。然而,并非所有的CI/CD工具都简单地支持排队运行。因此,在构建完整的CI/CD流程时,需要考虑这个问题。
除了竞态条件之外,还有其他一些问题和考虑因素。例如,可能需要处理敏感数据和凭据的安全性。建议使用安全的方式来存储和管理这些敏感信息,如使用密钥管理服务(KMS)或密钥管理工具(如HashiCorp的Vault)。
另一个重要的问题是如何处理Terraform状态文件。状态文件包含敏感信息和对基础设施状态的完整描述。应该确保安全地存储和管理状态文件,并且只有授权的人员能够访问它。
实现本地自动化需要投入精力来构建一个完整的CI/CD流程,并解决可能出现的问题和考虑因素。这将确保的Terraform工作流能够在可靠、安全和可持续的方式下运行。
3.使用开源软件
与Terraform一起使用的最流行的开源工具之一是Atlantis,它将自己描述为"Terraform pull request automation"。 Atlantis为团队提供了一种通过创建pull请求工作流来协作Terraform代码更改的方法。有了Atlantis,开发人员可以使用熟悉的基于git的工作流创建、审查和合并Terraform代码更改。Atlantis还提供自动化计划和应用工作流、自动分支清理以及与Slack和GitHub等流行协作工具集成等功能。 它不提供专用的用户界面,需要使用VCS提供商提供的用户界面,如果想使用更高级的功能,如Policy as Code或Drift Detection,则需要在管道内部创建集成,因为它没有自带这些。
4.使用Terraform Cloud
Terraform Cloud是由Terraform背后的公司hashicorp提供的一个应用程序。它是免费的,最多可为5个用户。有两种计划可供更多用户使用:"团队与治理"和"业务"。由于该产品是由Terraform作者自己创建的,因此任何使其加入Terraform的新功能也将很快在Terraform Cloud中可用。
优点
通过Sentinel提供的高级安全遵从机制允许在代码实际交付和创建具有所选提供者上下文的资源之前强制执行组织标准。 另一个重要的特性是模块注册中心,它充当所有模块的工件存储库。它可以与JFrog Artifactory, Sonatype Nexus或其他类似的软件进行比较。将每个模块放在单独的存储库和版本控制中可以让你以粒度方式控制代码升级,或者快速回滚到如果它只允许你回到最近的版本,那么我们应该使用"the",但如果它允许你回到其他更早的版本,那么我们应该使用"a"以前的版本。 有一个集中的位置来存储所有的部分,还使能够快速浏览可用的模块、它们的文档、输入、输出和使用的资源。在模块管理方面,它是一个很好的单一窗格。但是,它只能在同一个Terraform Cloud组织中使用,不能共享。对于基于组织级别的分离的运营团队来说,这可能会很麻烦。 还有远程执行后端,这是Terraform Cloud独有的功能。它允许像往常一样在本地计算机上使用Terraform,上传本地代码库,并针对它运行计划。这是一种非常有效的方法,可以快速验证所做的工作是否有效。
不足
虽然有这么多好处,但也有一些缺点。任何检测或模块单元测试都需要在自己的持续集成系统中实现。这需要开发团队付出额外的努力来维持他们的代码质量。 集成仅限于运行任务在任何给定时间所支持的内容,这意味着不能真正拥有自己的工作流。需要管理从Terraform Cloud接收的内容。 另一个缺点是无法控制操作(init/plan/apply)之前和之后发生的步骤。运行任务可以在计划之前或之后添加,也可以在应用之前添加,但不能在init之前或应用之后添加,这再次显示缺乏灵活性,并且需要在Github Action或任何其他CI/CD工具中构建管道,以便在运行代码之前做一些简单的检查。实际上可以做的唯一事情是使用CLI运行远程Terraform命令执行,这总体上没有多大帮助。 最大的缺点是Terraform Cloud不支持除Terraform之外的任何其他产品。当然,这不是它的目的,但由于许多组织都将Kubernetes和Ansible与Terraform结合使用,这意味着你需要采用其他工具,如ArgoCD和Ansible Tower来端到端管理你的工作流。
使用Spacelift平台
比较Spacelift和Terraform Cloud。就实际部署执行而言,它们彼此共享许多功能,而且在遵从性方面也是如此。 虽然Terraform Cloud主要使用Sentinel (HashiCorp方法作为代码实现合规性),但Spacelift利用Open Policy Agent。对于已经将OPA纳入其工作流程的公司(例如Kubernetes)来说,采用类似的方式处理策略是有益的。由于不需要学习另一种语法,操作人员可以将精力集中在提供遵从性上,而不是学习另一种工具。 使用Spacelift的自定义输入,可以轻松地将任何工具集成到的工作流中,但真正将其提升到下一个层次的是甚至可以为其编写策略。 希望tfscan作为工作流程的一部分吗?安装它并在before_init钩子中运行它,并将输出保存到一个格式为.custom.spacelift的文件中。Json(其中key可以是喜欢的任何内容)。在input.third_party_metadata.custom下访问计划策略中的数据。,可以编写任何想要的策略。不知道什么数据被暴露了? 使用Spacelift的策略工作台并处理数据,直到很容易理解可以根据集成工具的输出编写哪些策略。 Spacelift还允许进一步自动化工作流程。通过为模块提供内置的持续集成,可以非常快速地将测试或单元测试转移到一个专门用于Terraform的地方。它允许利用已经在使用的解决方案,从而帮助减少实现集成工作流所需的工作量。 Stack Dependencies可以帮助轻松地部署所需的所有内容,只需单击一下即可构建这些依赖项。由于堆栈依赖关系是有向无环图(DAG),一个堆栈可以依赖多个堆栈,也可以由多个堆栈依赖,但循环不存在。这开启了创建复杂工作流的可能性,而无需构建复杂的管道。 例如,有时需要直接使用Terraform状态来导入某些内容。在利用Terraform Cloud的场景中,如果不亲自访问提供商,通常不可能做到这一点。相比之下,Spacelift使能够通过任务在特定代码库的上下文中运行任何命令。这样,就不需要授予任何额外的权限来直接导入、移动或删除资源。 通过利用上下文,可以在多个堆栈之间简单地共享任何喜欢的内容---无论是一组环境变量还是一个文件。一旦代码库复杂性增加,这一点就会变得更有价值。 正如前一段所提到的,随着基础设施的发展,漂移检测变得更加重要。使用Spacelift,可以在任何堆栈上调度周期性漂移检测。更进一步,如果与代码库中的更改相比发现了任何更改,则可以启用自动修复
结论
有许多使用Terraform的方法。每种方法在复杂性方面都是不同的,并且具有不同的功能集。重要的是要记住,选择一种方式或另一种方式应该基于业务和技术需求。大多数时候,实现内部解决方案是没有意义的,因为构建和维护它的成本和工作可能经常超过它的潜在收益。