2016-04-13 00:11:09 +02:00
|
|
|
---
|
2020-10-27 01:58:30 +01:00
|
|
|
layout: "docs"
|
2016-04-13 00:11:09 +02:00
|
|
|
page_title: "Command: state mv"
|
2018-12-21 03:18:13 +01:00
|
|
|
sidebar_current: "docs-commands-state-sub-mv"
|
2016-04-13 00:11:09 +02:00
|
|
|
description: |-
|
2021-05-12 17:49:37 +02:00
|
|
|
The `terraform state mv` command changes bindings in Terraform state, associating existing remote objects with new resource instances.
|
2016-04-13 00:11:09 +02:00
|
|
|
---
|
|
|
|
|
|
|
|
# Command: state mv
|
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
The main function of [Terraform state](/docs/language/state/index.html) is
|
|
|
|
to track the bindings between resource instance addresses in your configuration
|
|
|
|
and the remote objects they represent. Normally Terraform 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 `terraform 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 Terraform, such as if you have renamed a resource block
|
|
|
|
or you have moved it into a different module in your configuration.
|
2016-04-13 00:11:09 +02:00
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
Usage: `terraform state mv [options] SOURCE DESTINATION`
|
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
Terraform 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](/docs/cli/state/resource-addressing.html), 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 `terraform 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 Terraform 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 `terraform state mv`
|
|
|
|
allows you to override that interpretation by pre-emptively attaching the
|
|
|
|
existing object to the new address in Terraform.
|
|
|
|
|
|
|
|
~> *Warning:* If you are using Terraform in a collaborative environment, you
|
|
|
|
must ensure that when you are using `terraform 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
|
|
|
|
`terraform 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.
|
|
|
|
|
2021-05-12 18:05:03 +02:00
|
|
|
This command also accepts the following options:
|
2021-05-12 17:49:37 +02:00
|
|
|
|
|
|
|
* `-dry-run` - Report all of the resource instances that match the given
|
|
|
|
address without actually "forgetting" any of them.
|
2021-05-11 20:37:32 +02:00
|
|
|
|
2021-05-12 18:05:03 +02:00
|
|
|
* `-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 Terraform 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.
|
|
|
|
|
2021-05-11 20:37:32 +02:00
|
|
|
For configurations using
|
|
|
|
[the `remote` backend](/docs/language/settings/backends/remote.html)
|
|
|
|
only, `terraform state mv`
|
|
|
|
also accepts the option
|
|
|
|
[`-ignore-remote-version`](/docs/language/settings/backends/remote.html#command-line-arguments).
|
|
|
|
|
|
|
|
For configurations using
|
|
|
|
[the `local` state mv](/docs/language/settings/backends/local.html) only,
|
|
|
|
`terraform taint` also accepts the legacy options
|
|
|
|
[`-state`, `-state-out`, and `-backup`](/docs/language/settings/backends/local.html#command-line-arguments).
|
backend: Validate remote backend Terraform version
When using the enhanced remote backend, a subset of all Terraform
operations are supported. Of these, only plan and apply can be executed
on the remote infrastructure (e.g. Terraform Cloud). Other operations
run locally and use the remote backend for state storage.
This causes problems when the local version of Terraform does not match
the configured version from the remote workspace. If the two versions
are incompatible, an `import` or `state mv` operation can cause the
remote workspace to be unusable until a manual fix is applied.
To prevent this from happening accidentally, this commit introduces a
check that the local Terraform version and the configured remote
workspace Terraform version are compatible. This check is skipped for
commands which do not write state, and can also be disabled by the use
of a new command-line flag, `-ignore-remote-version`.
Terraform version compatibility is defined as:
- For all releases before 0.14.0, local must exactly equal remote, as
two different versions cannot share state;
- 0.14.0 to 1.0.x are compatible, as we will not change the state
version number until at least Terraform 1.1.0;
- Versions after 1.1.0 must have the same major and minor versions, as
we will not change the state version number in a patch release.
If the two versions are incompatible, a diagnostic is displayed,
advising that the error can be suppressed with `-ignore-remote-version`.
When this flag is used, the diagnostic is still displayed, but as a
warning instead of an error.
Commands which will not write state can assert this fact by calling the
helper `meta.ignoreRemoteBackendVersionConflict`, which will disable the
checks. Those which can write state should instead call the helper
`meta.remoteBackendVersionCheck`, which will return diagnostics for
display.
In addition to these explicit paths for managing the version check, we
have an implicit check in the remote backend's state manager
initialization method. Both of the above helpers will disable this
check. This fallback is in place to ensure that future code paths which
access state cannot accidentally skip the remote version check.
2020-11-13 22:43:56 +01:00
|
|
|
|
2016-04-13 00:11:09 +02:00
|
|
|
## Example: Rename a Resource
|
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
Renaming a resource means making a configuration change like the following:
|
|
|
|
|
|
|
|
```diff
|
|
|
|
-resource "packet_device" "worker" {
|
|
|
|
+resource "packet_device" "helper" {
|
|
|
|
# ...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
To tell Terraform 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:
|
2016-04-13 00:11:09 +02:00
|
|
|
|
2019-08-03 01:36:24 +02:00
|
|
|
```shell
|
2021-05-12 17:49:37 +02:00
|
|
|
terraform state mv packet_device.worker packet_device.helper
|
2016-04-13 00:11:09 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
## Example: Move a Resource Into a Module
|
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
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 Terraform to treat it as a move:
|
2016-04-13 00:11:09 +02:00
|
|
|
|
2019-08-03 01:36:24 +02:00
|
|
|
```shell
|
2021-05-12 17:49:37 +02:00
|
|
|
terraform state mv packet_device.worker module.worker.packet_device.worker
|
2016-04-13 00:11:09 +02:00
|
|
|
```
|
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
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:
|
2016-04-13 00:21:51 +02:00
|
|
|
|
2019-08-03 01:36:24 +02:00
|
|
|
```shell
|
2021-05-12 17:49:37 +02:00
|
|
|
terraform state mv packet_device.worker module.worker.packet_device.main
|
2016-04-13 00:21:51 +02:00
|
|
|
```
|
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
## Example: Move a Module Into a Module
|
2016-04-13 00:11:09 +02:00
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
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:
|
2016-04-13 00:11:09 +02:00
|
|
|
|
2019-08-03 01:36:24 +02:00
|
|
|
```shell
|
2021-05-12 17:49:37 +02:00
|
|
|
terraform state mv module.app module.parent.module.app
|
2016-04-13 00:11:09 +02:00
|
|
|
```
|
2019-08-03 01:36:24 +02:00
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
## Example: Move a Particular Instance of a Resource using `count`
|
2019-08-03 01:36:24 +02:00
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
A resource defined with [the `count` meta-argument](/docs/language/meta-arguments/count.html)
|
|
|
|
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:
|
2019-08-03 01:36:24 +02:00
|
|
|
|
|
|
|
```shell
|
|
|
|
$ terraform state mv 'packet_device.worker[0]' 'packet_device.helper[0]'
|
|
|
|
```
|
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
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
|
|
|
|
$ terraform 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 Terraform.
|
|
|
|
The above examples show the typical quoting syntax for Unix-style shells.
|
|
|
|
|
2019-08-06 03:50:17 +02:00
|
|
|
## Example: Move a Resource configured with for_each
|
2019-08-03 01:36:24 +02:00
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
A resource defined with [the `for_each` meta-argument](/docs/language/meta-arguments/for_each.html)
|
|
|
|
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:
|
2019-08-03 01:36:24 +02:00
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
Unix-style shells, such as on Linux or macOS:
|
2019-08-03 01:36:24 +02:00
|
|
|
|
|
|
|
```shell
|
2021-05-12 17:49:37 +02:00
|
|
|
terraform state mv 'packet_device.worker["example123"]' 'packet_device.helper["example456"]'
|
2019-08-03 01:36:24 +02:00
|
|
|
```
|
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
Windows Command Prompt (`cmd.exe`):
|
2019-08-03 01:36:24 +02:00
|
|
|
|
|
|
|
```shell
|
2021-05-12 17:49:37 +02:00
|
|
|
terraform state mv packet_device.worker[\"example123\"] packet_device.helper[\"example456\"]
|
2019-08-03 01:36:24 +02:00
|
|
|
```
|
|
|
|
|
2021-05-12 17:49:37 +02:00
|
|
|
PowerShell:
|
2019-08-03 01:36:24 +02:00
|
|
|
|
|
|
|
```shell
|
2021-05-12 17:49:37 +02:00
|
|
|
terraform state mv 'packet_device.worker[\"example123\"]' 'packet_device.helper[\"example456\"]'
|
2016-04-13 00:11:09 +02:00
|
|
|
```
|
2021-05-12 17:49:37 +02:00
|
|
|
|
|
|
|
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.
|