命令:plan
tofu plan
命令创建一个执行计划,让你可以预览 OpenTofu 计划对你的基础设施进行的更改。默认情况下,当 OpenTofu 创建计划时,它会
- 读取任何已存在的远程对象的当前状态,以确保 OpenTofu 状态是最新的。
- 比较当前配置与先前状态,并记录任何差异。
- 提出一个更改操作集,这些操作如果应用,将使远程对象与配置匹配。
plan
命令本身不会执行建议的更改。你可以使用此命令来检查建议的更改是否符合你的预期,然后应用更改,或者与你的团队分享更改以进行更广泛的审查。
如果 OpenTofu 检测到资源实例或根模块输出值不需要进行任何更改,tofu plan
将报告不需要执行任何操作。
如果你在交互式终端中直接使用 OpenTofu,并且你希望应用 OpenTofu 提出的更改,则可以改为直接运行 tofu apply
。默认情况下,“apply” 命令会自动生成一个新计划,并提示你批准它。
可以使用可选的 -out=FILE
选项将生成的计划保存到磁盘上的文件,然后通过将文件作为额外参数传递给 tofu apply
来执行它。此两步工作流程主要用于在自动化中运行 OpenTofu 时。
如果你不使用 -out=FILE
选项运行 tofu plan
,那么它将创建一个推测性计划,它是计划的效果描述,但没有实际应用它的意图。
在使用版本控制和代码审查工作流程对真实基础设施进行更改的团队中,开发人员可以使用推测性计划来验证更改的效果,然后再将其提交以进行代码审查。但是,重要的是要考虑,在此期间对目标系统进行的其他更改可能会导致配置更改的最终效果与之前推测性计划所指示的效果不同,因此在应用之前,应始终重新检查最终的非推测性计划,以确保它仍然符合你的意图。
用法
用法:tofu plan [选项]
plan
子命令在当前工作目录中查找根模块配置。
由于 plan 命令是 OpenTofu 的主要命令之一,因此它具有各种不同的选项,将在以下部分进行描述。但是,大多数情况下,你应该不需要设置任何这些选项,因为 OpenTofu 配置通常应该被设计成在没有特殊额外选项的情况下用于日常工作。
此页面上的剩余部分将描述各种选项
- 计划模式:有一些特殊的备用计划模式,你可以在某些特殊情况下使用它们,在这种情况下,你的目标不仅仅是将远程系统更改为与你的配置匹配。
- 计划选项:除了特殊的计划模式之外,你还可以设置一些选项来为不寻常的需求自定义计划过程。
- 资源定位 是一种特殊的计划选项,它与某些重要的注意事项相关联。
- 其他选项:这些选项会更改计划命令本身的行为,而不是自定义生成的计划的内容。
计划模式
上一节描述了 OpenTofu 的默认计划行为,它将远程系统更改为与你对配置所做的更改相匹配。OpenTofu 有两种备用计划模式,每种模式都创建一个具有不同预期结果的计划。这些选项适用于 tofu plan
和 tofu apply
。
-
销毁模式: 创建一个计划,其目标是销毁当前存在的所有远程对象,留下一个空 OpenTofu 状态。它与运行
tofu destroy
相同。销毁模式对于诸如临时开发环境之类的场景非常有用,在这种场景中,受管对象在开发任务完成后将不再有用。使用
-destroy
命令行选项激活销毁模式。 -
仅刷新模式: 创建一个计划,其目标仅是更新 OpenTofu 状态和任何根模块输出值,以匹配对 OpenTofu 外部远程对象所做的更改。如果您有意在正常工作流程之外更改了一个或多个远程对象(例如在响应事件时),并且现在需要将 OpenTofu 的记录与这些更改协调,这将非常有用。
使用
-refresh-only
命令行选项激活仅刷新模式。
在需要讨论 OpenTofu 在未选择任何替代模式时使用的默认计划模式的情况下,我们将它称为“正常模式”。由于这些替代模式仅适用于特殊情况,因此其他 OpenTofu 文档仅讨论正常计划模式。
计划模式是互斥的,因此激活任何非默认计划模式都会禁用“正常”计划模式,并且您不能同时使用多个替代模式。
计划选项
除了备选的 计划模式 之外,还有几个选项可以修改计划行为。这些选项适用于 tofu plan
和 tofu apply
。
-
-refresh=false
- 禁用在检查配置更改之前将 OpenTofu 状态与远程对象同步的默认行为。这可以通过减少远程 API 请求次数来使计划操作更快。但是,设置refresh=false
会导致 OpenTofu 忽略外部更改,这可能导致计划不完整或不正确。您不能在仅刷新计划模式中使用refresh=false
,因为它会有效地禁用整个计划操作。 -
-replace=ADDRESS
- 指示 OpenTofu 计划用给定地址的资源实例替换现有资源实例。当一个或多个远程对象出现故障时,这很有帮助,您可以使用具有相同配置的替换对象来与不变基础设施模式保持一致。如果指定的资源通常会导致“更新”操作或根本不执行操作,OpenTofu 将使用“替换”操作。多次包含此选项以一次替换多个对象。您不能将-replace
与-destroy
选项一起使用。 -
-target=ADDRESS
- 指示 OpenTofu 将其计划工作重点放在与给定地址匹配的资源实例上,以及这些实例依赖的任何对象上。注意仅在特殊情况下使用
-target=ADDRESS
,例如从错误中恢复或绕过 OpenTofu 限制。有关更多详细信息,请参阅 资源定位。 -
-var 'NAME=VALUE'
- 为配置根模块中声明的单个 输入变量 设置值。多次使用此选项以设置多个变量。有关更多信息,请参阅 命令行上的输入变量。 -
-var-file=FILENAME
- 使用来自 "tfvars" 文件 的定义,为配置根模块中声明的许多 输入变量 设置值。多次使用此选项以包含来自多个文件的值。
除了 -var
和 -var-file
选项之外,还有几种其他方法可以为根模块中的输入变量设置值。有关更多信息,请参阅 将值分配给根模块变量。
命令行上的输入变量
您可以使用 -var
命令行选项为根模块中声明的 输入变量 指定值。
但是,这样做需要编写一个既可以被您选择的命令行 shell 又可以被 OpenTofu 解析的命令行,这对于涉及大量引号和转义序列的表达式来说可能很复杂。在大多数情况下,我们建议改为使用 -var-file
选项,并将实际值写入一个单独的文件,以便 OpenTofu 可以直接解析它们,而不是解释 shell 解析结果。
如果您在等号之前或之后包含空格(例如,-var "length = 2"
),OpenTofu 会报错。
要在 Linux 或 macOS 等系统上的类 Unix shell 上使用 -var
,我们建议将选项参数用单引号 '
括起来,以确保 shell 将按字面意思解释该值。
tofu plan -var 'name=value'
如果您的目标值也包含单引号,那么您仍然需要将其转义以确保 shell 正确解释,这还需要暂时结束引号序列,以便反斜杠转义字符具有意义。
tofu plan -var 'name=va'\''lue'
在 Windows 上使用 OpenTofu 时,我们建议使用 Windows 命令提示符 (cmd.exe
)。从 Windows 命令提示符将变量值传递给 OpenTofu 时,请使用双引号 "
括起参数。
tofu plan -var "name=value"
如果您的目标值包含文字双引号,则需要使用反斜杠对其进行转义。
tofu plan -var "name=va\"lue"
Windows 上的 PowerShell 无法将文字引号正确传递给外部程序,因此我们建议在 Windows 上使用 OpenTofu 时不要使用 PowerShell。请改用 Windows 命令提示符。
编写变量值的正确语法取决于变量的 类型约束。基本类型 string
、number
和 bool
都期望直接的字符串值,没有特殊标点符号,除了您的 shell 所需的标点符号,如上面的示例所示。对于所有其他类型约束,包括列表、映射和集合类型以及特殊的 any
关键字,您必须编写一个表示该值的有效 OpenTofu 语言表达式,并编写任何必要的引号或转义字符以确保它们会按字面意思传递到 OpenTofu。例如,对于 list(string)
类型约束。
# Unix-style shell
tofu plan -var 'name=["a", "b", "c"]'
# Windows Command Prompt (do not use PowerShell on Windows)
tofu plan -var "name=[\"a\", \"b\", \"c\"]"
使用环境变量设置输入变量时,也存在类似的约束。有关设置根模块输入变量的各种方法的更多信息,请参阅 将值分配给根模块变量。
资源定位
您可以使用 -target
选项将 OpenTofu 的注意力集中在资源的子集上。您可以使用 资源地址语法 来指定约束。OpenTofu 对资源地址的解释如下。
-
如果给定地址标识一个特定的资源实例,OpenTofu 将仅选择该实例。对于设置了
count
或for_each
的资源,资源实例地址必须包含实例索引部分,例如aws_instance.example[0]
。 -
如果给定地址标识一个资源作为一个整体,OpenTofu 将选择该资源的所有实例。对于设置了
count
或for_each
的资源,这意味着选择当前与该资源关联的所有实例索引。对于单实例资源(没有count
或for_each
),资源地址和资源实例地址相同,因此这种情况不适用。 -
如果给定地址标识整个模块实例,OpenTofu 将选择属于该模块实例及其所有子模块实例的所有资源的所有实例。
一旦 OpenTofu 选择了您直接定位的一个或多个资源实例,它还将扩展选择以包括这些选择直接或间接依赖的所有其他对象。
此定位功能是为特殊情况提供的,例如从错误中恢复或绕过 OpenTofu 限制。不建议将 -target
用于日常操作,因为这会导致未检测到的配置漂移,以及关于资源的真实状态如何与配置相关联的混淆。
与其将 -target
作为操作非常大型配置的隔离部分的一种方式,不如将大型配置分解成几个可以独立应用的较小配置。可以使用 数据源 访问在其他配置中创建的资源的信息,允许将复杂的系统架构分解成可以独立更新的更易于管理的部分。
其他选项
tofu plan
命令还有一些其他选项与计划命令的输入和输出相关,而不是自定义 OpenTofu 将创建哪种计划。除非在该命令的文档中另有说明,否则这些命令不一定也适用于 tofu apply
。
可用的选项有:
-
-compact-warnings
- 以紧凑形式显示任何警告消息,其中仅包含摘要消息,除非警告伴随至少一个错误,并且警告文本可能是错误的有用上下文。 -
-detailed-exitcode
- 命令退出时返回详细的退出代码。提供此参数时,此参数会更改退出代码及其含义,以提供有关结果计划包含的内容的更详细的信息。- 0 = 成功,差异为空(无更改)
- 1 = 错误
- 2 = 成功,差异不为空(存在更改)
-generate-config-out=PATH
- (实验性) 如果配置中存在import
块,则指示 OpenTofu 为任何不存在的导入资源生成 HCL。配置将写入 PATH 上的新文件,该文件必须不存在,否则 OpenTofu 会报错。如果计划因其他原因失败,OpenTofu 仍可能尝试写入配置。
-
-input=false
- 禁用 OpenTofu 的默认行为,该行为会提示用户输入未分配值的根模块输入变量。此选项在非交互式自动化系统中运行 OpenTofu 时特别有用。 -
-json
- 启用 机器可读的 JSON UI 输出。这意味着-input=false
,因此配置必须没有未分配的变量值才能继续。 -
-lock=false
- 在操作期间不保留状态锁。如果其他人可能同时对同一个工作区运行命令,这将很危险。 -
-lock-timeout=DURATION
- 除非使用-lock=false
禁用锁定,否则指示 OpenTofu 在返回错误之前尝试获取锁一段时间。持续时间语法是数字后跟时间单位字母,例如“3s”表示三秒钟。 -
-no-color
- 禁用输出中的终端格式化序列。如果在输出将由无法解释终端格式化的系统呈现的环境中运行 OpenTofu,请使用此选项。 -
-concise
- 以简洁的方式显示计划输出。它跳过显示刷新日志行。 -
-out=FILENAME
- 将生成的计划写入给定文件名中的不透明文件格式,您以后可以将其传递给tofu apply
以执行计划的更改,以及传递给可以处理已保存计划文件的其他一些 OpenTofu 命令。OpenTofu 允许使用任何文件名作为计划文件,但典型的约定是将其命名为
tfplan
。不要使用 OpenTofu 识别为其他文件格式的后缀命名文件;如果您使用.tf
或.tofu
后缀,那么 OpenTofu 将尝试将该文件解释为配置源文件,这将导致后续命令出现语法错误。生成的文件不是任何旨在供其他软件使用的标准格式,但该文件确实包含您的完整配置、与计划更改相关联的所有值以及所有计划选项(包括输入变量)。如果您的计划包含任何敏感数据,即使在 OpenTofu 的终端输出中被隐藏,它也会以明文形式保存在计划文件中。因此,您应该将任何已保存的计划文件视为可能敏感的工件。
-
-parallelism=n
- 限制 OpenTofu 遍历图形 时的并发操作数量。默认值为 10。
对于使用 local
后端 的配置,tofu plan
接受旧版命令行选项 -state
。
传递不同的配置目录
如果您的工作流程依赖于覆盖根模块目录,请使用 -chdir
全局选项,它适用于所有命令,并使 OpenTofu 在所有命令中始终在给定目录中查找它通常会在当前工作目录中读取或写入的所有文件。