terraform icon indicating copy to clipboard operation
terraform copied to clipboard

terraform state split

Open FernandoMiguel opened this issue 6 years ago • 8 comments

I would like to start discussion on adding a new terraform state command that would allow users to split statefiles into new smaller statefiles

the idea is that when a statefile grows too big, TF could manage to split those resources , moving some resources to a new statefile (and maybe update the corresponding backend ? )

Is this something terraform core could do in the future?

FernandoMiguel avatar Mar 22 '18 21:03 FernandoMiguel

Hi @FernandoMiguel! Thanks for starting this discussion.

This definitely seems like a good feature. The challenge, as I'm sure you can imagine, is in figuring out what is the right workflow/UX for it, since operations like this don't fit into some of the usual assumptions that the CLI commands make:

  • Operating on one configuration at a time
  • Operating on one backend at a time
  • Operating on one workspace at a time within that backend.

I think there is a plausible design to be found here, but we'll need to spend some time designing and prototyping to figure out what makes sense. Since our focus is elsewhere at the time of writing (on the configuration language) I'm going to label this to remind us to look at it in more detail in the future.


In the mean time it's possible to achieve some refactoring use-cases using the terraform state mv plumbing command. Its interface is somewhat clumsy due to the above constraints, but you can use it to move a single resource or an entire module into a new file:

$ terraform state mv -state-out=new.tfstate module.example module.example

The main limitation here is that this is a one-shot command that can only operate on one addressable object at a time, and so it's not well-suited to complex, multi-step refactoring tasks.

apparentlymart avatar Mar 22 '18 21:03 apparentlymart

thanks for taking this into consideration. let's hope the future brings this to a finished implementation

FernandoMiguel avatar Mar 22 '18 21:03 FernandoMiguel

Since this is 4 years old: are there any new, similar issues still under consideration? I would very much like to see a way to split state or move objects between remote state files.

jcogilvie avatar Jun 01 '22 19:06 jcogilvie

Since this command isn't implemented, but the needs are still there, here's a short description of how I did it recently in a somewhat automated way using existing terraform commands (tested on terraform ver: 1.2.6).

Prerequisites:

  • ensure that terraform does not have any pending changes (apply shows no changes). If you have any somewhat easy changes to introduce over all (unsplitted) resources - do it before the migration, it will be easier to do it now than later. It will be likely too hard to do it in the middle of migration.
  • ask your team to do not touch the repository & state file while you're splitting the state, as you'll need a full and explicit ownership over the process during the whole duration.
  • do a full backup of the state file (s3 and other) as well as repository, just in case you won't be able to get back to working state.
  • again, do not touch the state outside of migration. Do not introduce any changes or do anything that might disrupt the state file. You can introduce changes to resources after the split is done, not during, because it will confuse terraform.
  • the process works on basis of locally stored state file (terraform backend "local")

High level overview of the steps:

  1. Pull state to local file and reconfigure backend to use the local file
  2. Determine a list of resources to migrate by it's full path (module.name.aws_something.this etc) and save it to some file
  3. Create a new directory, move tf files with resources you want to migrate there and initialize it with empty local state file.
  4. Run a loop over each resource: cat $resources.txt | while read -r resource; do terraform state mv -state-out=new.tfstate "$resource" "$resource"; done. Do not use parallel or xargs - you will break JSON structure, this has to be done one-by-one. Take your time.
  5. Move the new state file to new directory with tf files describing the resources in state files.
  6. plan to see if all no difference is found (-> split is ok) or if some resources are missing/would be created (-> not everything was moved correctly).
  7. change backend to s3 (or other preferred) and reconfigure backend to upload the state
  8. done :)

arturtamborski avatar Aug 05 '22 11:08 arturtamborski

This would be so handy to have as a feature!

LyleHenkeman avatar Nov 01 '22 09:11 LyleHenkeman

Currently terraform split file looks as on https://support.hashicorp.com/hc/en-us/articles/7955227415059-How-to-Split-State-Files

but I see huge business case which can be very important.

We use a terraform to create primary and disaster recovery environment by defining second provider to other AWS region. It would be nice to have possibility to automatically split a state based on provider. This will be very crucial in case if one region of AWS will go down we still want to have management on secondary region

daroga0002 avatar Apr 06 '23 14:04 daroga0002

You could also use terraform-state-split cli which helps a lot with the process in big scale projects.

https://github.com/shebang-labs/terraform-state-split

Demo: https://asciinema.org/a/qqF2E5Uz2ybwzhJdMpuufzblu

Install:

brew tap shebang-labs/tap
brew install terraform-state-split

tareksamni avatar Jul 03 '23 15:07 tareksamni

Another tool capable of splitting one Terraform root module in two (split after and split before) is https://github.com/pix4D/terravalet (by me).

marco-m-pix4d avatar Jan 29 '24 09:01 marco-m-pix4d