Skip to content

fix(zone): prevent data source .zone_id from being mangled to .name_id#305

Open
koslib wants to merge 2 commits into
cloudflare:mainfrom
koslib:fix/zone-datasource-zone-id-rewrite
Open

fix(zone): prevent data source .zone_id from being mangled to .name_id#305
koslib wants to merge 2 commits into
cloudflare:mainfrom
koslib:fix/zone-datasource-zone-id-rewrite

Conversation

@koslib

@koslib koslib commented Jun 17, 2026

Copy link
Copy Markdown

Problem

When tf-migrate migrate processes configs that reference the zone data source's zone_id output (e.g. in import blocks or string interpolations), the migration produces an invalid reference:

# Input (v4)
id = "${data.cloudflare_zone.this.zone_id}/security_header"

# Buggy output
id = "${data.cloudflare_zone.this.name_id}/security_header"
# → Error: This object has no argument, nested block, or exported attribute named "name_id".

The correct v5 output is .id:

id = "${data.cloudflare_zone.this.id}/security_header"

Root cause

Two compounding issues introduced in #295:

  1. The regex built in applyGlobalPostprocessing for computed-attribute mappings had no trailing word boundary. The cloudflare_zone resource rule (\.zone.name) matched the prefix of .zone_id, silently rewriting it to .name_id.

  2. Because cloudflare_zone is an unanchored substring of data.cloudflare_zone, the resource rule also leaked onto data source references. The data.cloudflare_zone migrator had no mapping of its own to correctly handle its zone_id output attribute.

Fix

cmd/tf-migrate/main.go — add regexp.QuoteMeta and a trailing \b word boundary to both the computed-attribute-mapping and attribute-rename regex builders in applyGlobalPostprocessing. This prevents any attribute name from being matched as a prefix of a longer one, and ensures resource-type strings containing . are treated as literals.

internal/datasources/zone/v4_to_v5.go — add GetComputedAttributeMappings() to the data source migrator so cross-file zone_id output references are explicitly rewritten to id.

Tests

  • TestComputedAttrMappingBoundary (unit) — verifies the boundary fix: .zone_id is not touched by the resource rule, .zone_id is correctly rewritten to .id by the datasource rule, and valid .name references are preserved.
  • Scenario 8 in the zone_datasource integration fixture — covers an import block and output using .zone_id, asserting the output is .id.

Test layers run: make test (unit + integration) — all pass.

Related

Regression from #295.

koslib added 2 commits June 17, 2026 15:40
The computed-attribute mapping introduced for the cloudflare_zone resource
(rewriting .zone → .name) used an unanchored regex, causing two problems:

1. .zone matched the prefix of .zone_id, turning it into .name_id — an
   attribute that does not exist on the v5 zone data source.
2. cloudflare_zone also matched inside data.cloudflare_zone, so the
   resource rule leaked onto data source references.

Fix by adding regexp.QuoteMeta and a trailing word boundary (\b) to both
the computed-attribute-mapping and attribute-rename regex builders in
applyGlobalPostprocessing.

Add a ComputedAttributeMapping to the data.cloudflare_zone datasource
migrator so that cross-file references to the v4 zone_id output attribute
are correctly rewritten to the v5 id attribute.
Add TestComputedAttrMappingBoundary to verify that:
- The .zone → .name resource rule does not corrupt .zone_id references.
- The data.cloudflare_zone .zone_id → .id datasource rule fires correctly.
- Valid .name references on the data source are left untouched.

Extend the zone_datasource integration fixture with Scenario 8: an import
block and output using data.cloudflare_zone.by_id.zone_id, which must
become .id after migration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant