使用 Git 管理 Terraform 多个环境

Cai*_*ioT 3 git terraform

我研究并观看了一些有关管理多个环境的最佳方法的视频,但我仍然对如何以更好的方式管理它感到困惑。

假设我有一个具有以下结构的存储库:

main.tf
variables.tf
backend.tf
dev/
   variables.tfvar
   backend.dev.hcl
prod/
   variables.tfvar
   backend.production.hcl
Run Code Online (Sandbox Code Playgroud)

然后,在我的存储库中我有两个分支(dev 和 main)。将生产变量值提交给我的开发分支是否有意义?遵循最佳实践来处理这种情况的最佳方法是什么?

我的最后一个问题,一旦有任何更改提交到 dev 分支,将更改合并到 prod 分支而不丢失任何 dev/prod terraform 配置的最佳方法是什么?

先感谢您!

Mar*_*ins 8

这个问题的答案通常取决于您是在谈论 Terraform 配置本身的多个部署阶段,还是在 Terraform 管理的基础设施上运行的任何应用程序/服务的多个部署阶段。

考虑这种区别的一种方法是考虑您将使用多个阶段来实现什么目标。如果您的目标是在生产中执行之前有地方可以尝试运行,terraform apply那么您正在讨论 Terraform 配置的多个部署阶段。如果您的目标是创建一个长期存在的临时环境,以便将应用程序/服务部署到其中,那么从部署管道的角度来看,临时环境通常也是“生产”环境,因此通常应该如此对待。


要在将 Terraform 配置应用到“真实基础设施”之前对其进行测试,您可以使用Terraform CLI 工作区创建与您的配置关联的临时附加状态,以便您可以尝试应用更改,而不会影响“默认”工作区中表示的主要基础设施:

  • terraform workspace new temp-test创建临时工作区。
  • 使用版本控制系统选择工作区中最近应用的提交default。这通常位于版本控制存储库的主分支上,尽管根据您使用 VCS 的方式,您可能需要选择较早的提交以排除尚未应用于实际系统的任何更改。
  • terraform apply创建与默认工作区等效的基础架构,作为测试的基础。
  • 使用版本控制系统切换回您要测试的配置。这通常是存储库中的功能分支,可能附加到拉取请求。在此工作流程的真实版本中,以分支名称命名临时工作区可能会有所帮助,以便您的同事可以轻松查看哪些分支和工作区在一起。
  • terraform apply再次规划并应用新配置所代表的更改。
  • 如果应用成功,请检查它创建的基础设施,以确保它按照您预期的方式运行。
  • 当你完成后:
    • terraform destroy破坏temp-test基础设施
    • terraform workspace select返回默认工作区
    • terraform workspace delete temp-test删除临时工作区

为此,您需要小心避免在远程系统需要唯一名称的情况下与现有生产对象发生冲突。对于具有独立命名空间的帐户意识的系统,常见的选择是使用不同的帐户和完全独立的凭据进行测试,这意味着您可以使用远程系统的访问控制来避免“真实”基础设施的意外中断。


要创建一个长期存在的登台或开发环境,以便在其自己的部署管道期间测试某些更高级别的组件,需要不同的策略:在这种情况下,就应用程序的部署而言,支持登台环境的基础设施是“生产”的一部分涉及流程,因此通常应该这样建模。

为了实现这一目标,同时确保两个基础架构堆栈除了故意差异之外保持等效,请将通用基础架构代码分解为一个或多个模块,然后为生产基础架构调用这些模块一次,并为每个其他环境的基础架构调用一次这些模块。

根据系统的预期故障域,您可以选择在单个配置中同时表示生产和登台基础设施,其中包含对同一模块的两次调用:

module "network-production" {
  source = "../modules/network"

  cidr_block = "10.1.0.0/16"
  # etc...
}

module "network-production" {
  source = "../modules/network"

  cidr_block = "10.2.0.0/16"
  # etc...
}
Run Code Online (Sandbox Code Playgroud)

或者,为了确保它们都可以独立维护,您可以编写两个单独的配置,它们都调用同一个模块并terraform apply分别调用。

在这两种情况下,这里的想法是使用公共模块的输入变量来表示不同环境之间不可避免的差异,但在两种情况下保持声明的资源相同,但将它们都视为应用程序中的“生产基础设施”通过将它们都保存在名为 的命名空间中default(在一个配置中或跨多个配置),并通过在版本控制中使用相同的主分支来同时表示它们的“最新版本”,您可以从管道的角度来看。

如果您想测试对配置的更改,这些配置一起代表应用程序管道所依赖的所有环境,您可以通过创建一个代表整个堆栈或一个特定环境的临时工作区并将配置从一个分支应用到该工作区来组合这两种方法。 stack,然后将其合并到主分支并将其应用到默认工作区。


此答案是对 Terraform 文档何时使用多个工作空间中的指南的详细阐述。

但最终,在这种情况下,您有几种不同的选择和不同的权衡,我鼓励您查看此建议和文档中的其他相关上下文,并自行决定哪些建议最符合您的需求。Terraform 是一个通用工具,旨在解决各种不同的问题,最终只有您可以将您的特定需求集映射到 Terraform 的功能上。