diff --git a/integration/v4_to_v5/testdata/zone/expected/zone_cross_refs.tf b/integration/v4_to_v5/testdata/zone/expected/zone_cross_refs.tf new file mode 100644 index 00000000..95a3ac76 --- /dev/null +++ b/integration/v4_to_v5/testdata/zone/expected/zone_cross_refs.tf @@ -0,0 +1,37 @@ +# Cross-file references to cloudflare_zone.*.zone +# These should be rewritten to .name after migration + + + +# Pattern: .zone reference in a local +locals { + cftftest_zone_domain = cloudflare_zone.minimal.name +} + +# Pattern: Direct .zone reference in another resource +resource "cloudflare_dns_record" "cftftest_zone_ref" { + zone_id = cloudflare_zone.minimal.id + name = cloudflare_zone.minimal.name + type = "CNAME" + content = "example.com" + ttl = 1 +} + +moved { + from = cloudflare_record.cftftest_zone_ref + to = cloudflare_dns_record.cftftest_zone_ref +} + +# Pattern: .zone reference in string interpolation +resource "cloudflare_dns_record" "cftftest_zone_interpolation" { + zone_id = cloudflare_zone.minimal.id + name = "cftftest-sub.${cloudflare_zone.minimal.name}" + type = "CNAME" + content = "example.com" + ttl = 1 +} + +moved { + from = cloudflare_record.cftftest_zone_interpolation + to = cloudflare_dns_record.cftftest_zone_interpolation +} diff --git a/integration/v4_to_v5/testdata/zone/input/zone_cross_refs.tf b/integration/v4_to_v5/testdata/zone/input/zone_cross_refs.tf new file mode 100644 index 00000000..5c172d9a --- /dev/null +++ b/integration/v4_to_v5/testdata/zone/input/zone_cross_refs.tf @@ -0,0 +1,23 @@ +# Cross-file references to cloudflare_zone.*.zone +# These should be rewritten to .name after migration + +# Pattern: Direct .zone reference in another resource +resource "cloudflare_record" "cftftest_zone_ref" { + zone_id = cloudflare_zone.minimal.id + name = cloudflare_zone.minimal.zone + type = "CNAME" + content = "example.com" +} + +# Pattern: .zone reference in string interpolation +resource "cloudflare_record" "cftftest_zone_interpolation" { + zone_id = cloudflare_zone.minimal.id + name = "cftftest-sub.${cloudflare_zone.minimal.zone}" + type = "CNAME" + content = "example.com" +} + +# Pattern: .zone reference in a local +locals { + cftftest_zone_domain = cloudflare_zone.minimal.zone +} diff --git a/internal/resources/zone/v4_to_v5.go b/internal/resources/zone/v4_to_v5.go index a6ae0d0e..b42906d1 100644 --- a/internal/resources/zone/v4_to_v5.go +++ b/internal/resources/zone/v4_to_v5.go @@ -47,6 +47,21 @@ func (m *V4ToV5Migrator) GetResourceRename() ([]string, string) { return []string{"cloudflare_zone"}, "cloudflare_zone" } +// GetComputedAttributeMappings implements the ComputedAttributeMapper interface. +// In v4, the zone's domain was accessed as cloudflare_zone.example.zone. +// In v5, it's cloudflare_zone.example.name. This enables cross-file reference +// rewriting so that any resource referencing .zone gets updated to .name. +func (m *V4ToV5Migrator) GetComputedAttributeMappings() []transform.ComputedAttributeMapping { + return []transform.ComputedAttributeMapping{ + { + OldResourceType: "cloudflare_zone", + OldAttribute: "zone", + NewResourceType: "cloudflare_zone", + NewAttribute: "name", + }, + } +} + // TransformConfig handles configuration file transformations. // Transformations: // 1. zone → name @@ -103,4 +118,3 @@ func (m *V4ToV5Migrator) setAccountNestedAttribute(body *hclwrite.Body, accountI // Set the account attribute with the nested object body.SetAttributeRaw("account", tokens) } -