Skip to content

fix(zero_trust_access_group): unwrap single-element list attrs to scalars - #321

Merged
ssicard merged 1 commit into
mainfrom
fix/azure-ad-id-list-to-scalar
Aug 20, 2026
Merged

fix(zero_trust_access_group): unwrap single-element list attrs to scalars#321
ssicard merged 1 commit into
mainfrom
fix/azure-ad-id-list-to-scalar

Conversation

@musa-cf

@musa-cf musa-cf commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Problem

In v4, azure.id, gsuite.email, and okta.name are lists. In v5, these are scalar strings (azure_ad.id, gsuite.email, okta.name). The migrator was preserving the list wrapper, producing id = [value] instead of id = value, causing string required, but have tuple errors on terraform apply.

Fix

Add unwrapSingleElementList helper that converts single-element list attributes to scalar values during migration. Called from expandAzure, expandGsuite, and expandOkta. Handles:

  • Literal values: id = ["group-id"] -> id = "group-id"
  • Variable references: id = [each.value] -> id = each.value
  • Already-scalar values: no-op (safe for configs that don't use list form)

Tests

  • 6 new unit tests covering azure (literal, variable ref, already-renamed resource, already-scalar), gsuite, and okta
  • 3 new integration test patterns (25-27)
  • All existing tests continue to pass
$ go test ./internal/resources/zero_trust_access_group/... -v -count=1

=== RUN   TestConfigTransformation
=== RUN   TestConfigTransformation/basic_resource_rename
=== RUN   TestConfigTransformation/multiple_email_selectors
=== RUN   TestConfigTransformation/multiple_selector_types
=== RUN   TestConfigTransformation/boolean_selectors
=== RUN   TestConfigTransformation/email_domain_with_field_rename
=== RUN   TestConfigTransformation/geo_with_field_rename
=== RUN   TestConfigTransformation/service_token_with_field_rename
=== RUN   TestConfigTransformation/device_posture_with_field_rename
=== RUN   TestConfigTransformation/common_name_scalar
=== RUN   TestConfigTransformation/common_names_overflow_array
=== RUN   TestConfigTransformation/auth_method_scalar
=== RUN   TestConfigTransformation/all_three_rule_types
=== RUN   TestConfigTransformation/github_teams_explosion
=== RUN   TestConfigTransformation/github_teams_explosion_with_resource_reference_identity_provider_id
=== RUN   TestConfigTransformation/external_evaluation_block_conversion
=== RUN   TestConfigTransformation/auth_context_block_conversion
=== RUN   TestConfigTransformation/azure_block_with_list_id_literal
=== RUN   TestConfigTransformation/azure_block_with_list_id_variable_reference
=== RUN   TestConfigTransformation/azure_block_with_list_id_-_already_renamed_resource_type_(exact_user_report_APIX-1110)
=== RUN   TestConfigTransformation/azure_block_with_scalar_id_(already_unwrapped)
=== RUN   TestConfigTransformation/gsuite_block_with_list_email
=== RUN   TestConfigTransformation/okta_block_with_list_name
=== RUN   TestConfigTransformation/complex_multi-selector
=== RUN   TestConfigTransformation/cf_terraforming_multiple_include_blocks
=== RUN   TestConfigTransformation/cf_terraforming_mixed_conditions
=== RUN   TestConfigTransformation/cf_terraforming_boolean_selectors_empty_objects
=== RUN   TestConfigTransformation/cf_terraforming_email_domain_selector
=== RUN   TestConfigTransformation/cf_terraforming_geo_selector
=== RUN   TestConfigTransformation/cf_terraforming_login_method_device_posture
=== RUN   TestConfigTransformation/cf_terraforming_any_valid_service_token
=== RUN   TestConfigTransformation/cf_terraforming_common_name_auth_method
=== RUN   TestConfigTransformation/cf_terraforming_ip_list_email_list
=== RUN   TestConfigTransformation/cf_terraforming_group_service_token
--- PASS: TestConfigTransformation (0.02s)
    --- PASS: TestConfigTransformation/azure_block_with_list_id_literal (0.00s)
    --- PASS: TestConfigTransformation/azure_block_with_list_id_variable_reference (0.00s)
    --- PASS: TestConfigTransformation/azure_block_with_list_id_-_already_renamed_resource_type_(exact_user_report_APIX-1110) (0.00s)
    --- PASS: TestConfigTransformation/azure_block_with_scalar_id_(already_unwrapped) (0.00s)
    --- PASS: TestConfigTransformation/gsuite_block_with_list_email (0.00s)
    --- PASS: TestConfigTransformation/okta_block_with_list_name (0.00s)
    (remaining 28 subtests PASS)
PASS
ok  github.com/cloudflare/tf-migrate/internal/resources/zero_trust_access_group  0.691s

$ go test ./integration/v4_to_v5/... -v -count=1

--- PASS: TestV4ToV5Migration (46.58s)
    --- PASS: TestV4ToV5Migration/zero_trust_access_group (0.32s)
    (remaining 44 subtests PASS)
PASS
ok  github.com/cloudflare/tf-migrate/integration/v4_to_v5  47.633s

Fixes #302

…lars (#302)

In v4, azure.id, gsuite.email, and okta.name are lists. In v5, these
are scalar strings (azure_ad.id, gsuite.email, okta.name). The migrator
was preserving the list wrapper, producing id = [value] instead of
id = value, causing 'string required, but have tuple' errors on apply.

Add unwrapSingleElementList helper and call it in expandAzure,
expandGsuite, and expandOkta. Handles both literal values and variable
references (e.g. each.value). No-ops when the attribute is already a
scalar.

Fixes: #302
@musa-cf
musa-cf requested a review from a team as a code owner August 18, 2026 20:30
@ssicard
ssicard merged commit 2b1333f into main Aug 20, 2026
11 checks passed
@ssicard
ssicard deleted the fix/azure-ad-id-list-to-scalar branch August 20, 2026 20:11
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.

Fails to migrate cloudflare_zero_trust_access_group.include.azure_ad.id

2 participants