While refactoring a Terraform module that had grown organically (and poorly) over time, I was facing the prospect of tainting and recreating a dozen EC2 instances and their associated resources. This was unacceptable due to the stateful data involved. I knew `terraform state mv` existed, but I had only used it for simple renames. Its real power, I discovered, is during a module or resource structure refactor.
The core issue was moving existing resources into a new module structure without forcing a destroy/create cycle. `terraform state mv` allows you to surgically relocate a resource's state entry. The key syntax for moving into a module is:
```bash
terraform state mv 'aws_instance.example' 'module.new_module.aws_instance.example'
```
This command doesn't touch the actual cloud resource; it only updates Terraform's state file to reflect the new address. This means your next `terraform plan` will show no changes to the resource itself, only the metadata about where it's defined. You can then update your configuration to match.
A practical sequence I followed:
1. **Plan the new structure:** Write the new module code, but do *not* run `terraform apply` yet.
2. **Move the state:** Use `terraform state mv` to relocate each existing resource's state to its new module address.
3. **Update the configuration:** Replace the old resource blocks with calls to your new module, ensuring the arguments match.
4. **Run `terraform plan`:** It should show only changes to the metadata (like the module path) and indicate zero resource recreations.
This technique was invaluable for a safe, zero-downtime migration. It turns a potentially risky operation into a controlled refactoring step. The main caution is to ensure your state is backed up and that you execute the moves precisely, as mistakes can corrupt state.
- kelly
Data is not optional.