These are utlity scripts that really should be JS or TS.
Generate a terraform refactor configuration file based on the git diff of a terraform configuration file.
Currently only supports:
- Renaming resources
- Renaming modules
References:
git diff HEAD~ HEAD -- ./terraform/modules/atlantis/iam.tf | diff_refactor.py > ./terraform/modules/atlantis/iam-refactor.tfNote
Just use git diff -- <file-path> if you haven't committed your changes yet.
use git diff --name-only | grep .tf to get a list of changed terraform config files.
python3 -m unittest test_diff_refactor.pyGenerate a terraform refactor configuration file based on the terraform plan output.
Warning
Use git diff for better results, unless you use CDKTF and didn't write moved statements in your CDKTF code...
This is a lot more complicated and requires manual tuning once the script completed.
A moved block cannot change a resource's type. When a provider renames a
resource type but the underlying cloud object is the same and importable under
the new type, the clean migration is a removed (forget, don't destroy) + import
(re-adopt the same object) pair. plan_refactor.py emits these automatically for
type pairs listed in the RESOURCE_TYPE_MIGRATIONS allow-list, deriving the
import id from the destroyed resource's attributes in the plan.
Seeded example: cloudflare_record → cloudflare_dns_record (Cloudflare provider
v4 → v5), import id "<zone_id>/<record_id>".
# type-migration cloudflare_record.foo -> cloudflare_dns_record.foo
removed {
from = cloudflare_record.foo
lifecycle {
destroy = false
}
}
import {
to = cloudflare_dns_record.foo
id = "<zone_id>/<record_id>"
}
Important
Only add a pair to RESOURCE_TYPE_MIGRATIONS when the new type can import the
identical object the old type manages. Do not add genuine object changes
such as aws_iam_policy → aws_iam_role_policy (a standalone managed policy and
an inline role policy are different AWS objects — import has no existing target
and removed would orphan the managed policy). Those are real replacements and
the script correctly leaves them in the # NOTE: unmatched section.
terraform plan -no-color > tfplan
plan_refactor.py tfplan > refactor.tfpython3 -m unittest test_plan_refactor.py