跳至主要内容

命令:state mv

OpenTofu 状态 的主要功能是跟踪配置中资源实例地址与它们表示的远程对象之间的绑定关系。通常,OpenTofu 会在应用计划时采取的操作(例如,删除现在已删除的远程对象的绑定)后自动更新状态。

在您希望保留现有远程对象但将其作为 OpenTofu 中不同的资源实例地址进行跟踪的不太常见的情况下,可以使用 tofu state mv,例如,如果您已重命名资源块或将其移动到配置中的不同模块中。

用法

用法:tofu state mv [选项] 源 目标

OpenTofu 将在当前状态中查找与给定地址匹配的资源实例、资源或模块,如果成功,它将把当前与源关联的远程对象移动到目标进行跟踪。

源地址和目标地址都必须使用 资源地址语法,并且它们都必须引用相同类型的对象:您只能将资源实例移动到另一个资源实例,将整个模块实例移动到另一个整个模块实例等。此外,如果您正在移动资源或资源实例,则只能将其移动到具有相同资源类型的新的地址。

tofu state mv 最常见的用法是当您已重命名配置中的资源块或已将资源块移动到子模块中时,在这两种情况下,都希望保留现有对象,但在新名称下对其进行跟踪。默认情况下,OpenTofu 会将移动或重命名资源配置理解为删除旧对象并在新地址创建新对象的请求,因此 tofu state mv 允许您通过在 OpenTofu 中抢先将现有对象附加到新地址来覆盖此解释。

此命令还接受以下选项

  • -dry-run - 报告与给定地址匹配的所有资源实例,而无需实际“忘记”任何实例。

  • -lock=false - 在操作期间不持有状态锁。如果其他人可能同时对同一工作区运行命令,则此操作很危险。

  • -lock-timeout=DURATION - 除非使用 -lock=false 禁用锁定,否则指示 OpenTofu 在返回错误之前尝试获取锁一段时间。持续时间语法为数字后跟时间单位字母,例如“3s”表示三秒。

  • -var 'NAME=VALUE' - 为配置根模块中声明的单个输入变量设置值。多次使用此选项可设置多个变量。有关更多信息,请参阅命令行上的输入变量

  • -var-file=FILENAME - 使用来自“tfvars”文件的定义,为配置根模块中声明的可能多个输入变量设置值。多次使用此选项可包含来自多个文件的值。

除了 -var-var-file 选项外,还有几种其他方法可以为根模块中的输入变量设置值。有关更多信息,请参阅为根模块变量赋值

仅对于使用cloud 后端remote 后端的配置,tofu state mv 还接受选项-ignore-remote-version

旧版选项-backup-backup-out仅对本地状态文件进行操作。使用remote 后端的配置必须使用-state选项指定本地状态文件才能使用-backup-backup-out选项。

仅对于使用local 状态 mv的配置,tofu state mv 还接受旧版选项-state-state-out-backup-backup-out

示例:重命名资源

重命名资源意味着进行如下配置更改

代码块
-resource "packet_device" "worker" {
+resource "packet_device" "helper" {
# ...
}

要告诉 OpenTofu 它应该将新的“helper”资源视为旧的“worker”资源的重命名,您可以将上述配置更改与以下命令配对

代码块
tofu state mv packet_device.worker packet_device.helper

示例:将资源移动到模块中

如果您最初在根模块中编写了资源,但现在希望将其重构到子模块中,您可以将 resource 块移动到子模块配置中,删除根模块中的原始资源,然后运行以下命令告诉 OpenTofu 将其视为移动操作

代码块
tofu state mv packet_device.worker module.worker.packet_device.worker

在上面的示例中,新资源具有相同的名称,但模块地址不同。如果新的模块组织建议使用不同的命名方案,您也可以同时更改资源名称。

代码块
tofu state mv packet_device.worker module.worker.packet_device.main

示例:将模块移动到模块中

您还可以将整个模块重构到子模块中。在配置中,将表示模块的 module 块移动到另一个模块,然后将此更改与以下命令配对

代码块
tofu state mv module.app module.parent.module.app

示例:使用 count 移动资源的特定实例

使用count 元参数定义的资源有多个实例,每个实例都由一个整数标识。您可以通过在给定地址中包含显式索引来选择特定实例。

代码块
$ tofu state mv 'packet_device.worker[0]' 'packet_device.helper[0]'

不使用 countfor_each 的资源只有一个资源实例,其地址与资源本身相同,因此您可以从不包含索引的地址移动到包含索引的地址,反之亦然,只要您使用的地址类型与每个资源的配置方式(是否以及如何配置)相匹配即可。

代码块
$ tofu state mv 'packet_device.main' 'packet_device.all[0]'

方括号([])在某些 shell 中具有特殊含义,因此您可能需要引用或转义地址才能将其逐字传递给 OpenTofu。以上示例显示了 Unix 风格 shell 的典型引用语法。

示例:移动使用 for_each 配置的资源

使用for_each 元参数定义的资源有多个实例,每个实例都由一个字符串标识。您可以通过在给定地址中包含显式键来选择特定实例。

但是,字符串的语法包括引号,并且引号符号在命令 shell 中通常具有特殊含义,因此您需要使用 shell 所使用的适当的引用和/或转义语法。例如

Unix 风格的 shell,例如 Linux 或 macOS 上的 shell

代码块
tofu state mv 'packet_device.worker["example123"]' 'packet_device.helper["example456"]'

Windows 命令提示符 (cmd.exe)

代码块
tofu state mv packet_device.worker[\"example123\"] packet_device.helper[\"example456\"]

PowerShell

代码块
tofu state mv 'packet_device.worker[\"example123\"]' 'packet_device.helper[\"example456\"]'

除了使用字符串而不是整数作为实例键外,for_each 资源的处理方式与 count 资源类似,因此与上一节中描述的相同地址组合(带索引组件和不带索引组件)都是有效的。