---
description: >-
  The `tofu state mv` command changes bindings in OpenTofu state,
  associating existing remote objects with new resource instances.
---

# Command: state mv

The main function of [OpenTofu state](../../../language/state/index.mdx) is
to track the bindings between resource instance addresses in your configuration
and the remote objects they represent. Normally OpenTofu automatically
updates the state in response to actions taken when applying a plan, such as
removing a binding for an remote object that has now been deleted.

You can use `tofu state mv` in the less common situation where you wish
to retain an existing remote object but track it as a different resource
instance address in OpenTofu, such as if you have renamed a resource block
or you have moved it into a different module in your configuration.

## Usage

Usage: `tofu state mv [options] SOURCE DESTINATION`

OpenTofu will look in the current state for a resource instance, resource,
or module that matches the given address, and if successful it will move the
remote objects currently associated with the source to be tracked instead
by the destination.

Both the source and destination addresses must use
[resource address syntax](../../../cli/state/resource-addressing.mdx), and
they must both refer to the same kind of object: you can only move a resource
instance to another resource instance, a whole module instance to another
whole module instance, etc. Furthermore, if you are moving a resource or
a resource instance then you can only move it to a new address with the
same resource type.

The most common uses for `tofu state mv` are when you have renamed a
resource block in your configuration or you've moved a resource block into
a child module, in both cases with the intention of retaining the existing
object but tracking it under a new name. By default OpenTofu will understand
moving or renaming a resource configuration as a request to delete the old
object and create a new object at the new address, and so `tofu state mv`
allows you to override that interpretation by pre-emptively attaching the
existing object to the new address in OpenTofu.

:::warning
If you are using OpenTofu in a collaborative environment, you
must ensure that when you are using `tofu state mv` for a code refactoring
purpose you communicate carefully with your coworkers to ensure that nobody
makes any other changes between your configuration change and your
`tofu state mv` command, because otherwise they might inadvertently create
a plan that will destroy the old object and create a new object at the new
address.
:::

:::note
Use of variables in [module sources](../../../language/modules/sources.mdx#support-for-variable-and-local-evaluation),
[backend configuration](../../../language/settings/backends/configuration.mdx#variables-and-locals),
or [encryption block](../../../language/state/encryption.mdx#configuration)
requires [assigning values to root module variables](../../../language/values/variables.mdx#assigning-values-to-root-module-variables)
when running `tofu state mv`.
:::

This command also accepts the following options:

- `-dry-run` - Report all of the resource instances that match the given
  address without actually "forgetting" any of them.

- `-lock=false` - Don't hold a state lock during the operation. This is
  dangerous if others might concurrently run commands against the same
  workspace.

- `-lock-timeout=DURATION` - Unless locking is disabled with `-lock=false`,
  instructs OpenTofu to retry acquiring a lock for a period of time before
  returning an error. The duration syntax is a number followed by a time
  unit letter, such as "3s" for three seconds.

* `-var 'NAME=VALUE'` - Sets a value for a single
  [input variable](../../../language/values/variables.mdx) declared in the
  root module of the configuration. Use this option multiple times to set
  more than one variable. Refer to
  [Input Variables on the Command Line](../plan.mdx#input-variables-on-the-command-line) for more information.

* `-var-file=FILENAME` - Sets values for potentially many
  [input variables](../../../language/values/variables.mdx) declared in the
  root module of the configuration, using definitions from a
  ["tfvars" file](../../../language/values/variables.mdx#variable-definitions-tfvars-files).
  Use this option multiple times to include values from more than one file.

* `-json` - Enables the [machine readable JSON UI](../../../internals/machine-readable-ui.mdx) output.

* `-json-into=out.json` - Produces the same output as -json, but redirected to a file. This allows
  for simultaneous capture of both human readable and machine readable logs.

There are several other ways to set values for input variables in the root
module, aside from the `-var` and `-var-file` options. Refer to
[Assigning Values to Root Module Variables](../../../language/values/variables.mdx#assigning-values-to-root-module-variables) for more information.

For configurations using the [`cloud` backend](../../../cli/cloud/index.mdx) or the [`remote` backend](../../../language/settings/backends/remote.mdx)
only, `tofu state mv`
also accepts the option
[`-ignore-remote-version`](../../../cli/cloud/command-line-arguments.mdx#ignore-remote-version).

The legacy options [`-backup` and `-backup-out`](../../../language/settings/backends/local.mdx#command-line-arguments)
operate on a local state file only. Configurations using
[the `remote` backend](../../../language/settings/backends/remote.mdx)
must specify a local state file with the [`-state`](../../../language/settings/backends/local.mdx#command-line-arguments)
option in order to use the [`-backup` and `-backup-out`](../../../language/settings/backends/local.mdx#command-line-arguments)
options.

For configurations using
[the `local` state mv](../../../language/settings/backends/local.mdx) only,
`tofu state mv` also accepts the legacy options
[`-state`, `-state-out`, `-backup`, and `-backup-out`](../../../language/settings/backends/local.mdx#command-line-arguments).

## Example: Rename a Resource

Renaming a resource means making a configuration change like the following:

```diff
-resource "packet_device" "worker" {
+resource "packet_device" "helper" {
   # ...
 }
```

To tell OpenTofu that it should treat the new "helper" resource as a rename
of the old "worker" resource, you can pair the above configuration change
with the following command:

```shell
tofu state mv packet_device.worker packet_device.helper
```

## Example: Move a Resource Into a Module

If you originally wrote a resource in your root module but now wish to refactor
it into a child module, you can move the `resource` block into the child
module configuration, removing the original in the root module, and then
run the following command to tell OpenTofu to treat it as a move:

```shell
tofu state mv packet_device.worker module.worker.packet_device.worker
```

In the above example the new resource has the same name but a different module
address. You could also change the resource name at the same time, if the new
module organization suggests a different naming scheme:

```shell
tofu state mv packet_device.worker module.worker.packet_device.main
```

## Example: Move a Module Into a Module

You can also refactor an entire module into a child module. In the
configuration, move the `module` block representing the module into a different
module and then pair that change with a command like the following:

```shell
tofu state mv module.app module.parent.module.app
```

## Example: Move a Particular Instance of a Resource using `count`

A resource defined with [the `count` meta-argument](../../../language/meta-arguments/count.mdx)
has multiple instances that are each identified by an integer. You can
select a particular instance by including an explicit index in your given
address:

```shell
$ tofu state mv 'packet_device.worker[0]' 'packet_device.helper[0]'
```

A resource that doesn't use `count` or `for_each` has only a single resource
instance whose address is the same as the resource itself, and so you can
move from an address not containing an index to an address containing an index,
or the opposite, as long as the address type you use matches whether and how
each resource is configured:

```shell
$ tofu state mv 'packet_device.main' 'packet_device.all[0]'
```

Brackets (`[`, `]`) have a special meaning in some shells, so you may need to
quote or escape the address in order to pass it literally to OpenTofu.
The above examples show the typical quoting syntax for Unix-style shells.

## Example: Move a Resource configured with for_each

A resource defined with [the `for_each` meta-argument](../../../language/meta-arguments/for_each.mdx)
has multiple instances that are each identified by an string. You can
select a particular instance by including an explicit key in your given
address.

However, the syntax for strings includes quotes and the quote symbol often
has special meaning in command shells, so you'll need to use the appropriate
quoting and/or escaping syntax for the shell you are using. For example:

Unix-style shells, such as on Linux or macOS:

```shell
tofu state mv 'packet_device.worker["example123"]' 'packet_device.helper["example456"]'
```

Windows Command Prompt (`cmd.exe`):

```shell
tofu state mv packet_device.worker[\"example123\"] packet_device.helper[\"example456\"]
```

PowerShell:

```shell
tofu state mv 'packet_device.worker[\"example123\"]' 'packet_device.helper[\"example456\"]'
```

Aside from the use of strings instead of integers for instance keys, the
treatment of `for_each` resources is similar to `count` resources and so
the same combinations of addresses with and without index components is
valid as described in the previous section.
