Terraform
Terraform v1.x 兼容性承诺
Terraform v1.0 的发布是 Terraform 语言和工作流程开发中的一个重要里程碑。Terraform v1.0 是一个稳定平台,用于描述和管理基础设施。
在此版本中,我们定义了 Terraform 的一些行为,我们打算在整个 1.x 版本中保持兼容性。
- Terraform 语言功能的一个大部分子集。
- Terraform CLI 工作流程命令的一个更保守的子集。
- Terraform Core 和 Terraform 供应商之间通信的线路协议。
- Terraform 供应商和外部 Terraform 模块安装的线路协议。
我们的意图是,为 Terraform v1.0 编写的 Terraform 模块将在整个 v1.x 版本中继续成功规划和应用,无需进行任何更改。
我们还打算,围绕本文档中描述的工作流程子集构建的自动化将在所有未来的 v1.x 版本中无需更改即可工作。
最后,我们打算,根据当前文档中的供应商线路协议构建的供应商将与所有未来针对相同操作系统和架构的 Terraform v1.x 版本兼容,无需修改源代码或重新编译二进制文件。
简而言之,我们的目标是使 v1.x 版本之间的升级变得简单直接,无需更改您的配置,无需运行额外的命令来执行升级步骤,也无需更改您为 Terraform 设置的任何自动化。
Terraform v1.x 系列在 v1.0 发布后将至少积极维护 18 个月。
以下各节包含一些关于我们将在 v1.x 系列中承诺的具体指导,供那些希望了解完整细节的人参考。然而,从更高层次来看,我们不打算进行任何更改,以至于在升级到新的 v1.x 版本时,现有模块或自动化需要进行更改。除非有非常充分的理由(例如解决关键安全问题或与不受我们直接控制的远程依赖项的破坏性更改相匹配),否则我们通常会将新的 Terraform CLI 版本中的兼容性问题视为需要修复的错误。
Terraform 语言
主要的 Terraform 语言包括语言语法、顶级结构(如 resource、module 和 provider 块)、这些块中的“元参数”以及表达式中可用的运算符和内置函数的文档化语义和行为。
Terraform 语言没有单一的正式规范,但 Terraform 网站上的配置部分作为语言功能及其预期行为的描述。
以下顶级块及其定义的“元参数”(即由 Terraform Core 而非外部插件(如提供程序)定义的参数)将保留其当前功能
resource和data块用于声明资源,包括其嵌套块类型lifecycle、connection和provisioner,以及它们的元参数provider。module块用于调用其他模块,及其元参数providers。resource、data和module块中的count、for_each和depends_on元参数。provider块用于配置提供程序,以及alias元参数。variable、output和locals块用于声明模块中各种命名的值。terraform块,包括嵌套的required_version和required_providers参数,以及用于后端配置的嵌套backend块。
我们还打算保持与所有 表达式运算符 和 内置函数 的兼容性,但引用 terraform.workspace 除外,其行为可能会随着工作空间模型的未来更改而改变。
我们打算保持与 Terraform 语言功能的广泛兼容性,但有一些具体的注意事项
如果 Terraform 可以创建并应用计划而不报告任何错误,则我们认为配置是有效的。
目前产生错误的配置可能会在未来的 Terraform 版本中产生不同的错误或表现出其他非错误行为。在应用阶段产生错误的配置在未来可能会在更早的阶段产生类似的错误,因为我们通常认为尽早检测错误会更好。
通常而言,本文档中描述的兼容性承诺仅适用于有效配置。无效配置的处理始终可能在未来的 Terraform 版本中发生变化。
如果某个功能的实际行为与我们明确记录的功能行为不同,我们通常会将其视为错误并更改该功能以匹配文档,但如果这些更改可能导致广泛的兼容性问题,我们将避免进行此类更改。我们无法承诺始终与以前的版本“错误兼容”,但我们将仔细考虑此类修复,以最大程度地减少其影响。
任何实验性功能都可能在未来的版本中更改或完全删除。当实验性语言功能处于活动状态时,Terraform 始终会发出警告,以提醒您注意该风险。我们不建议在生产模块中使用实验性功能。
我们将引入新的语言功能,如果您开始使用它们,那么您的配置将无法与尚不支持这些功能的早期 Terraform 版本一起使用。
Terraform 提供程序是独立的插件,可以独立于 Terraform Core 进行更改,因此不受这些兼容性承诺的约束。如果您升级您正在使用的任何提供程序,则可能需要更改与这些提供程序相关的提供程序或资源配置。
少数功能在 Terraform v1.0 中仍然被弃用并带有明确警告。这些弃用周期将在未来的 v1.x 版本中结束,届时我们将删除相应的功能。
工作流程
有一组常用的 Terraform 工作流程,我们称之为 *受保护工作流程*。我们不会删除这些命令、子命令和标志,也不会对受保护工作流程功能进行向后不兼容的更改。如果意外更改了这些,我们将把核心工作流程的向后不兼容更改视为需要修复的错误。有关属于受保护工作流程的命令和选项组合列表,请参阅受保护工作流程命令。还有一组命令我们明确 *不* 作兼容性承诺,因为我们预计它们的功能将在 v1.x 版本中发生变化:请参阅可能更改的命令。
外部软件与 Terraform 交互的受支持方式是通过某些命令提供的 JSON 输出模式以及退出状态码。我们可能会通过新的对象属性扩展某些 JSON 格式,但我们不会删除或对现有属性的定义进行破坏性更改。
自然语言命令输出或日志输出不是稳定的接口,并且可能在任何新版本中发生变化。如果您编写解析此输出的软件,则在升级 Terraform 时可能需要更新该软件。如果您需要访问目前无法通过机器可读的 JSON 接口获得的数据,我们建议您提出功能请求以讨论您的用例。
升级与降级
在 v1.x 系列版本中,我们打算您应该能够切换到更新的 Terraform 版本,并像以前一样使用它,无需任何特殊的升级步骤。
您应该能够从任何 v1.x 版本升级到任何更高版本的 v1.x 版本。您也可能能够降级到更早的 v1.x 版本,但这不能保证:后来的版本可能会引入早期版本无法理解的新功能,包括 Terraform 状态快照的新存储格式。
如果您使用较晚的 v1.x 版本中引入的功能,您的配置将无法与早于该功能的版本兼容。例如,如果 v1.3 中添加了一项语言功能,并且您开始使用它,您的 Terraform 配置将不再与 Terraform v1.2 兼容。
提供程序
Terraform 提供程序是独立的插件,使用文档化的协议与 Terraform 通信。因此,这些兼容性承诺只能涵盖 Terraform Core 实现的此协议的“客户端”方面;单个提供程序的行为,包括它们支持的资源类型和它们期望的参数,由提供程序开发团队决定,并且可以独立于 Terraform Core 版本进行更改。
如果您升级到提供程序的新版本,即使您仍在使用 Terraform v1.x 版本,您也可能需要更改由该提供程序解释的配置部分。
提供程序安装方法
Terraform 通常从实现 提供程序注册协议 版本 1 的提供程序注册中心安装提供程序。所有 Terraform v1.x 版本都将与该协议保持兼容,因此正确实现的提供程序注册中心将保持兼容。
Terraform 还支持从 本地文件系统目录(文件系统镜像)和 网络镜像(实现 提供程序镜像协议)安装提供程序。所有 Terraform v1.x 版本都将与这些安装方法保持兼容,包括 隐式本地镜像目录。
特定的提供程序注册表或网络镜像独立于 Terraform 本身运行,因此它们自身的行为不受这些兼容性承诺的约束。
提供程序协议版本
截至 Terraform v1.0,提供程序插件协议的当前主要版本是版本 5,它由描述物理线路格式的 Protocol Buffers 架构和描述预期提供程序行为的附加散文文档相结合定义。
我们将在 Terraform v1.x 版本中支持协议版本 5。如果我们在以后的版本中对协议版本 5 进行新的次要修订,我们将对其进行设计,以便现有插件将继续工作,只要它们正确实现了协议。
我们可能会在 v1.x 系列中引入新的主要协议版本。如果这样做,我们将继续支持协议版本 5 以及这些新版本。个别提供程序团队可能会决定在以后的版本中删除对协议版本 5 的支持,在这种情况下,这些新的提供程序版本将与所有 Terraform v1.x 版本不兼容。
外部模块
Terraform 模块是用 Terraform 语言编写的可重用基础设施组件。有些模块是“外部”的,这意味着 Terraform 会自动从当前配置目录以外的位置安装它们,在这种情况下,它们的内容可能会独立于您本地模块、您使用的提供程序和 Terraform 本身的变化而变化。
模块安装方法
Terraform 支持从多种不同的模块源类型安装子模块。我们将在所有 v1.x 版本中继续支持所有现有的源类型。
其中一种支持的源类型是实现模块注册协议版本 1 的模块注册表。所有 Terraform v1.x 版本都将与该协议的正确实现保持兼容。
某些模块源类型直接与第三方定义和运行的服务或协议一起使用。尽管我们不会删除 Terraform 自身对这些协议的客户端支持,但我们无法保证其所有者会保持这些服务运行或它们会与 Terraform 的客户端实现保持兼容。
外部模块兼容性
如果您的配置依赖于外部模块,这些模块的较新版本可能包含破坏性更改。外部模块不属于 Terraform,因此不受这些兼容性承诺的约束。
配置器
我们将通过所有 v1.x 版本保持对 file、local-exec 和 remote-exec 配置器类型的兼容性。
一些额外的供应商特定配置器在早期 Terraform 版本中可用,但在 Terraform v0.13 中被弃用,并在 Terraform v0.15 中被移除。
Terraform 支持从某些本地文件系统目录将附加的配置程序作为插件加载。我们将在 Terraform v1.x 版本中继续支持这一点,但由于此类插件与 Terraform Core 本身是分离的,因此它们的行为不受这些兼容性承诺的约束。但是,我们将继续支持 Terraform v1.0 中定义的插件线路协议,贯穿整个 v1.x 版本,因此正确实现的配置程序插件应与未来的 Terraform 版本保持兼容。
状态存储后端
当您使用 *远程状态* 时,Terraform 会通过网络与远程服务交互,以存储和管理 Terraform 状态的锁。
由于历史原因,所有支持的状态存储后端都包含在 Terraform CLI 中,但并非所有后端都直接由 Terraform 团队支持。只有以下由 Terraform 团队维护的后端受兼容性承诺的约束:
其他状态存储后端由外部团队通过对 Terraform CLI 代码库的贡献来维护,因此它们的预期配置参数或行为即使在 v1.x 版本中也可能发生变化,尽管我们将在这种情况下尽可能地确保良好的迁移路径。
我们正在考虑通过插件允许外部状态存储后端实现,类似于提供程序插件。如果在 v1.x 版本中引入此类机制,您可能需要进行配置更改才能使用这些插件,并且一旦等效插件可用,上述列表之外的状态存储后端可能会从未来的 Terraform CLI 版本中删除。
remote 后端和 HCP Terraform
remote 后端由 HCP Terraform 团队维护,因此其行为可能会随着 HCP Terraform 的持续变化而改变。
在整个 v1.x 版本中,将有一个受支持的机制来将 Terraform CLI 与 HCP Terraform 结合使用,但具体细节可能会发生变化。HCP Terraform 独立于 Terraform CLI 发展,因此不受这些兼容性承诺的约束。
社区维护的状态存储后端
azurerm、consul、s3 和 kubernetes 后端由 HashiCorp 的其他团队维护。这些团队打算在 v1.x 版本中继续进行基本维护(错误修复),除非我们实现一个用于后端的插件协议,届时这些后端的开发很可能只在外部插件中继续进行,这可能需要更改配置才能切换到插件等效项。
cos、oss、pg、gcs 和 etcdv3 后端由外部贡献者维护,不受这些兼容性承诺的约束。
未维护的状态存储后端
artifactory、etcdv2、manta 和 swift 状态存储后端目前没有维护者,因此它们将尽力保留在 Terraform CLI 版本中。它们可能会在未来的 v1.x 版本中被移除,并且如果它们集成的服务有任何破坏性更改,它们将不会更新。
支持的平台
在整个 v1.x 系列中,我们将继续为以下平台发布官方版本,并根据需要进行更改以支持这些操作系统的新版本:
- x64 CPU 上的 macOS (
darwin_amd64) - x64 CPU 上的 Windows (
windows_amd64) - x64、32 位 ARMv6 和 64 位 ARMv8 上的 Linux(分别为
linux_amd64、linux_arm和linux_arm64)
随着时间的推移,我们可能需要这些操作系统的新版本。例如,v1.x 系列中后续的 Terraform 版本可能会终止对早期 macOS 或 Windows 版本,或早期 Linux 内核版本的支持。
我们历来为许多其他平台发布官方版本,以方便这些平台的用户,目前我们没有停止发布的计划,但我们无法承诺在整个 v1.x 系列中为其他平台持续发布或修复错误。我们通常不会在上述平台以外的任何平台上测试 Terraform。
我们可能会在未来的 v1.x 版本中增加对新平台的支持。如果发生这种情况,在这些支持之前发布的早期 Terraform 版本将无法在这些平台上使用。
所有 Terraform 插件,包括提供程序插件,都是独立的程序,它们有自己的支持平台策略。我们无法保证所有提供程序目前都支持或将继续支持上述平台,即使 Terraform CLI 本身会支持它们。
这些承诺的后续修订
我们可能会在整个 v1.x 系列中扩展或完善这些承诺,以描述与新功能相关的承诺,或在通过反馈发现我们之前的陈述不清楚时澄清现有承诺。
新功能的承诺将是附加的,即它们将增加额外的承诺,而不会撤回任何现有承诺。对于仅适用于后续 v1.x 版本的承诺,我们将提及这些承诺适用的最早版本。
即使我们没有在此文档中添加明确声明,我们仍打算在后续 v1.x 版本中添加的任何非实验性功能至少在 v1.x 系列的其余部分保持兼容,除非另有说明。
附录
受保护的工作流程命令
以下是受这些兼容性承诺约束的 Terraform CLI 子命令和选项列表。如果您围绕这些命令构建自动化,那么它应该与所有后续的 v1.x 版本兼容。
如上所述,与外部软件的兼容性仅限于明确的机器可读输出(-json 和 -raw 模式)和退出代码。这些命令的任何自然语言输出都可能在以后的版本中发生变化。
initvalidateplanapplyshowproviders(无子命令)providers lockproviders mirrorproviders schemafmtversionoutputtaintuntaintforce-unlockstate liststate pullstate pushstate showlogin
对于上述列表之外的命令或选项,我们仍将尽可能避免破坏性更改,但无法保证在整个v1.x系列中保持完全兼容性。如果您正在围绕Terraform构建自动化,请仅使用上述命令,以避免在升级时需要进行更改。
请注意,尽管Terraform的内部日志(通过TF_LOG环境变量)以JSON格式提供,但这些日志行的特定语法或结构_不是_受支持的集成接口。日志以JSON格式提供仅是为了帮助Terraform开发人员进行临时过滤和处理日志。
可能更改的命令
以下所有命令及其子命令/选项_不_受兼容性承诺约束,原因是我们已计划在v1.x系列中改进它们,或者我们意识到其设计中存在可能需要破坏性更改才能持续维护的缺陷。
只要这些命令仍受支持,您就可以在交互式运行Terraform时自由使用它们,但我们不建议将其作为任何自动化的一部分使用,除非您愿意在升级到更高版本的v1.x发行版时可能更新该自动化。
destroy(考虑使用terraform apply -destroy代替)consoleget(考虑使用terraform init代替)graphimportpushrefresh(考虑使用terraform apply -refresh-only代替)state mvstate replace-providerstate rmworkspace的所有子命令(及其已弃用的别名env)
尽管我们确实打算在未来的版本中保留对这些命令主要用例的支持,但我们无法保证保留用于满足这些用例的精确命令名称或选项。
我们将如何兑现这些承诺
自动化回归测试
Terraform 代码库包含各种单元测试和集成测试,旨在帮助我们在稳定版本发布前发现意外的行为回归。
然而,Terraform 是一个相对复杂的系统,具有许多可能以有趣方式相互作用的不同功能。过去我们曾收到报告,称只有当我们将两个或更多功能以我们先前未曾预期或未编写自动化测试的方式组合时,才会出现行为差异。
在每种情况下,我们都实施了更改来解决兼容性问题,_并_添加了一个或多个代表该功能组合行为的集成测试。我们打算继续这种方法,以便我们可以随着时间的推移改进 Terraform 的测试覆盖范围。
预发布版本
我们希望这些承诺所涵盖的大多数意外行为更改都能被现有测试捕获。然而,我们也承认我们的测试套件永远无法完美覆盖所有可能的功能交互或其他边缘情况,因此我们的目标是在最终发布之前,将每个重要更改都包含在 Alpha 和 Beta 版本中。
对于次要版本,我们通常也会在最终发布之前至少发布一个候选发布版本。候选发布版本表示计划的开发已经完成,并且我们已经修复了根据 Alpha 和 Beta 版本报告的任何回归,因此随后的最终发布通常应该与最新候选发布版本完全或几乎完全匹配。
最终发布中的回归
对于更复杂的特性组合,回归可能在预发布期间未被检测到,从而包含在最终版本中。
如果在发布后不久有人发现并报告了此类回归,我们将将其视为错误并修复它,以在未来的版本中恢复先前的行为,除非有非常重要的理由,例如安全建议。在这些情况下,我们通常会建议受回归影响的任何人继续使用以前的版本,直到问题得到修复,然后直接跳到包含该修复的新版本。
您可以通过主动针对 Alpha、Beta 和发布候选包测试模块来最大程度地降低受最终发布中未发现的回归影响的风险。我们建议仅在隔离的开发或 staging 环境中执行此操作,而不是针对生产基础设施。如果您在预发布版本中发现行为更改与本文档中的承诺不符,请在 Terraform 的 GitHub 仓库中提出问题进行讨论。
迟报的回归
在最极端的情况下,某个特性组合的回归可能非常罕见,以至于长时间未被发现。
在某个更改包含在更多发布版本中后,其他用户依赖新行为的可能性会越来越大,因此我们需要权衡,决定恢复旧行为是否会比保留新行为带来更大的负面影响。我们将始终根据每个独特情况的影响进行慎重决策。
您可以通过及时升级到 Terraform 的新次要版本和补丁版本,并在 Terraform 的 GitHub 仓库中报告您遇到的任何兼容性问题,从而最大程度地降低您的模块受迟报回归影响的风险。
实际例外
我们真诚地做出上述承诺,旨在确保您在编写 Terraform 模块或自动化方面的投入不会因 Terraform 未来的更改而失效。然而,像上述这样宽泛的承诺不可能涵盖我们在持续开发 Terraform 过程中可能出现的所有实际问题的细微差别。
因此,在某些情况下,我们可能仍需要进行更改,这可能会影响现有模块或自动化:
- 安全问题:我们可能会意识到一个重要的安全设计问题。根据我们对相关风险的判断,我们可能会选择打破兼容性以实现更安全的系统。
- 外部依赖:Terraform 的行为依赖于外部代码库提供的接口,包括您选择的操作系统,以及在模块和提供程序安装等情况下的某些远程网络服务。这些外部系统可能在我们无法控制的情况下发生变化,包括可能删除或更改 Terraform 自身功能所依赖的特性。在这种情况下,如果没有合适的替代机制,我们可能需要更改 Terraform 的设计以适应新的约束。
- 选择性兼容性破坏:新语言功能的设计可能需要更改现有功能的行为或配置表示。如果是这样,我们通常会使新功能仅为选择性加入,以避免破坏现有模块,但如果您更改模块以选择性加入新功能,那么您可能还需要更改配置的其他部分以适应新的语言设计。
- 新功能中的错误:如果我们向 Terraform 引入新功能,并且初始实现存在问题导致其与发布时文档中描述的设计意图不符,我们可能会发布后续版本,纠正实现以匹配文档中的设计,即使这与初始实现相比代表了轻微的兼容性回归。但是,一旦某个功能成熟并被广泛使用,我们通常会遵循已实现的行为,并相应地修改文档以反映它。
- 现有功能中的回归:如果我们发现新的 Terraform 版本包含现有功能的回归,并且在开发和预发布期间未检测到,并且在新的发布后立即发现,我们通常会恢复先前的行为,尽管这在技术上打破了与新发布行为的兼容性,但我们假设受回归影响的用户系统会比依赖新引入行为的用户系统更多。
- 迟报的回归:如前一节所述,如果我们了解到在更早的版本中存在一个很少使用或组合的功能的意外回归,那么恢复先前的行为可能会被后来的采用者视为回归。如果我们认为修复回归会影响比回归本身影响更多的用户,那么我们可能会选择接受该回归作为新的承诺行为。
- 我们无法预料的情况:尽管我们已努力在此处考虑各种特定的例外情况,但 Terraform 及其开发过程并非与更广泛的环境隔离,因此我们必须考虑可能存在我们无法预料的情况,这些情况可能会影响 Terraform 的未来。在这些情况下,我们将始终尽最大努力寻找一种行动方案,以尽可能最大限度地减少对现有模块和自动化的影响。
我们设定这些实际例外情况的意图只是为了承认,总会有一般兼容性承诺无法解决的情况。我们将仅在充分考虑并作为最后手段时使用这些例外。