Last Updated: 2026-02-06 by Keming He
Important
Platform-agnostic - Terraform CLI works identically on macOS, Linux, and Windows.
Diagnose and execute state migrations when refactoring Terraform projects.
State addresses follow this format:
module.<instance_name>.resource_type.resource_name[key]
| Change | Migration Required |
|---|---|
Rename module "old" to module "new" |
Yes |
Rename resource "type" "old" to "new" |
Yes |
Change for_each keys |
Yes |
Change module source path |
No |
| Rename variables | No |
| Change resource attributes | No |
Rule: If the state address changes, migration is required.
terraform plan| Plan Output | Meaning |
|---|---|
~ update in-place |
Safe - no migration needed |
-/+ destroy and create |
Stop - migration needed |
If you see destroy/create for resources you want to keep, perform state migration before applying.
Best for simple renames.
# Backup first
terraform state pull > backup.tfstate
# Move resource
terraform state mv 'module.old.aws_vpc.main' 'module.new.aws_vpc.main'
# Move entire module
terraform state mv 'module.old' 'module.new'
# Verify
terraform plan # Should show no changesBest for team coordination and version-controlled migrations.
moved {
from = module.old
to = module.new
}Terraform handles migration automatically on next apply.
Best for complex restructuring.
# Backup
terraform state pull > backup.tfstate
# Remove from state (infrastructure unchanged)
terraform state rm 'aws_s3_bucket.old'
# Update code, then import
terraform import 'aws_s3_bucket.new["key"]' bucket-id
# Verify
terraform plan# module.legacy_vpc -> module.vpc
terraform state mv 'module.legacy_vpc' 'module.vpc'# aws_vpc.main_vpc -> aws_vpc.network
terraform state mv 'module.vpc.aws_vpc.main_vpc' 'module.vpc.aws_vpc.network'# Individual resources -> for_each loop
terraform state rm 'aws_s3_bucket.data_dev'
terraform state rm 'aws_s3_bucket.data_prod'
# After updating code
terraform import 'aws_s3_bucket.data["dev"]' data-dev
terraform import 'aws_s3_bucket.data["prod"]' data-prodBefore:
- Backup:
terraform state pull > backup.tfstate - Document:
terraform state list > current.txt - Test in non-production first
During:
- One resource at a time
- Verify after each move:
terraform planshould show no changes
After:
- Confirm:
terraform planshows no unexpected changes - Backup final state
Strategy Selection:
| Situation | Use |
|---|---|
| Simple rename | state mv |
| Team refactoring | moved block |
| Complex restructuring | Import after remove |