这个问题的答案通常取决于您是在谈论 Terraform 配置的多个部署阶段本身,还是您将在 Terraform 上运行的任何应用程序/服务的多个部署阶段 -托管基础设施。
考虑这种区别的一种方法是考虑您将使用多个阶段来实现什么。如果您的目标是在生产环境中尝试运行terraform apply,那么您就是在谈论 Terraform 配置的多个部署阶段。如果您的目标是创建一个长期存在的暂存环境,以便您将应用程序/服务部署到其中,那么从部署管道的角度来看,暂存环境通常也是“生产”环境,因此通常应该这样对待。
要在将 Terraform 配置应用到“真实基础架构”之前对其进行测试,您可以使用 Terraform CLI workspaces 创建与您的配置相关联的临时附加状态,这样您就可以尝试应用更改而不影响“默认”中表示的主要基础架构" 工作区:
-
terraform workspace new temp-test 创建一个临时工作区。
- 使用您的版本控制系统选择最近在
default 工作区中应用的提交。这通常位于版本控制存储库的主分支上,但根据您使用 VCS 的方式,您可能需要选择较早的提交以排除尚未应用于实际系统的任何更改。
-
terraform apply 创建与默认工作区等效的基础架构,作为测试的基础。
- 使用您的版本控制系统切换回您要测试的配置。这通常是存储库中的功能分支,可能附加到拉取请求。在此工作流的真实版本中,以您的分支名称命名临时工作区可能会有所帮助,这样您的同事就可以轻松查看哪些分支和工作区放在一起。
-
terraform apply 再次计划和应用新配置所代表的更改。
- 如果应用成功,请检查它创建的基础架构以确保其按您预期的方式运行。
- 完成后:
-
terraform destroy 破坏 temp-test 基础设施
-
terraform workspace select 回到默认工作区
-
terraform workspace delete temp-test删除临时工作区
为此,您需要小心避免在远程系统需要唯一名称的情况下与现有生产对象发生冲突。对于具有不同命名空间的帐户的系统,一个常见的选择是使用不同的帐户和完全独立的凭据进行测试,这意味着您可以使用远程系统的访问控制来避免“真实”基础设施的意外中断.
要创建一个长寿命的暂存或开发环境,以便在其自己的部署管道期间测试某些更高级别的组件,需要采用不同的策略:在这种情况下,支持暂存环境的基础架构是“生产”的一部分,只要涉及到应用程序的部署过程,因此通常应该这样建模。
为实现这一目标,同时确保两个基础架构堆栈除了有意的差异外保持相同,请将您的通用基础架构代码分解为一个或多个 modules,然后为生产基础架构调用这些模块一次,然后再为彼此环境的基础架构调用这些模块.
根据您系统的预期故障域,您可以选择在一个配置中同时表示生产和暂存基础架构,其中包含对同一模块的两次调用:
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...
}
或者,为了确保它们都可以独立维护,您可以编写两个单独的配置,它们都调用同一个模块并分别terraform apply它们。
在这两种情况下,这里的想法是使用公共模块的输入变量来表示不同环境之间不可避免的差异,但在两种情况下保持声明的资源相同,但将它们都视为“生产基础设施”从应用程序管道的角度来看,通过将它们都保存在一个名为 default 的命名空间中,无论是在一个配置中还是在多个配置中,并通过在版本控制中使用相同的主分支来同时表示它们的“最新版本”。
如果您想测试对您的配置所做的更改,这些更改共同代表您的应用程序的管道所依赖的所有环境,您可以通过创建一个代表整个堆栈或一个特定环境的临时工作区并应用来自在将其合并到主分支之前分支到该堆栈并将其应用到默认工作区。
此答案是对 Terraform 文档 When to use Multiple Workspaces 中指南的详细说明。
但最终,在这种情况下,您有几个不同的选项需要权衡取舍,我建议您查看此建议和文档中的其他相关上下文,并自行决定哪些建议最符合您的需求. Terraform 是一种通用工具,旨在解决各种不同的问题,最终只有您可以将您的特定需求集映射到 Terraform 的功能。