Merging two states involves moving resources from one to the other using using
terraform state mv [options] SOURCE DESTINATION [a].
Note: Use the version of Terraform that matches the *desired end state* to perform the operations.
1. Obtain both state files. If the configuration has an appropriate backend configuration, this can be done with
terraform state pull > source.tfstateand
terraform state pull > destination.tfstate[b]
If no backend is configured, the state files can be downloaded directly from their backends (i.e. S3 bucket or Terraform Enterprise workspace).
2. Backup creation. Make a copy of both state files for backups.
3. Create a new, empty directory and place the two states that will be merged into it. This ensures that there are no initialized backend configurations or other state files that may conflict with the following commands.
4. Identify which state will be the end state. In my example I will use
destination.tfstateas the final state. I will move resources from
5. View Resources. To view the existing resources in the destination state, use
terraform state list -state=destination.tfstate > destination-resources.txt. Use
terraform state list -state=source.tfstate > source-resources.txtto view the existing resource in the source state. The `-state` flag is listed legacy, however its necessary when working with two state files in one directory [c].
Note: If you wish for all resources in both states to be present in the merged/end state, all of the resource addresses must be unique [d].
6. Move top level resources and top level modules. For each top level resource (e.g.
aws_instance.foo) and top level module (e.g.
module.bar) listed for
source.tfstate, perform a
terraform state mvto move the resource from the source to the destination [a].
Resources inside modules and modules inside modules (e.g.
module.baz.module.qux) should not need to be moved, as they will be moved along with the top level modules.
Example: Using local backend, add options
terraform state mv -state=source.tfstate -state-out=destination.tfstate aws_instance.foo aws_instance.foo
terraform state mv -state=source.tfstate -state-out=destination.tfstate module.bar module.bar
7. View source state and destination state files. Once all of the top level resources and modules have been moved, the source state should be empty, which can be checked with
terraform state list -state=source.tfstate. All resources should now exist in the destination state, which can be checked similarly with
terraform state list -state=destination.tfstate.
destination.tfstatein a text editor and increment the "serial" value by
9. Upload new, merged state to its final destination. Either (1) Copy the state back to the backend destination manually, such as upload the state to an S3 destination, or (2) upload the state to the backend destination of the merged configuration using
terraform state push, or (3) use the Terraform Cloud / Enterprise API to create a new state version [e].
Example: Upload state to the backend destination using terraform state push command.
# In the directory where the combined configuration has been initialized using `terraform init`
terraform state push path/to/destination.tfstate
10. Review. The combined state is now in place and should be ready for use with a combined configuration. Use
terraform state listto view the state list information from the state in the backend, which was just pushed. Run
terraform planto see the results and ensure that they are as expected. If the configuration was combined and the states were combined, this should likely show no changes.
If changes are proposed and this is unexpected, then review the changes to determine the next steps. Either the state or the configuration will require additional modification. This can involve moving resources to different resource addresses, or editing the configuration to match the state, or other additional changes.