Skip to content

terraform test: override_data fails with nested_type attributes (Plugin Framework providers) #38369

@ei-grad

Description

@ei-grad

Description

terraform test fails when using override_data with values for data sources that use the Plugin Framework's nested_type schema representation. HCL list literals ([{ ... }]) produce tuple types, and fillAttribute in the mocking package rejects them with:

Error: Failed to compute attribute

Terraform could not compute a value for the target type list of object with
the mocked data with the attribute ".result": incompatible types; expected object type, found tuple.

This makes terraform test mocking unusable for providers built entirely with the Plugin Framework — most notably Cloudflare provider v5, which has 397 resources/data sources using nested_type.

The bug is in the fillAttribute function and is unrelated to override_during — it triggers with or without it.

Root cause

In internal/moduletest/mocking/fill.go, fillAttribute checks in.Type().IsObjectType() before inspecting the nesting mode. For NestingSingle/NestingGroup this is correct, but for NestingList/NestingSet/NestingMap the input value is a collection (tuple/list/set/map), not an object.

The existing fillType function already handles tuple→list coercion correctly for type-based schemas (SDKv2 providers), but the fillAttribute path for nested_type schemas (Plugin Framework providers) does not.

Reproduction

Tested on Terraform v1.11.4 and v1.14.3, Cloudflare provider v5.18.0.

Note: OpenTofu v1.11.5 does NOT have this bug — same test passes there.

Cloudflare (FAILS)

# main.tf
terraform {
  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 5.0"
    }
  }
}

data "cloudflare_accounts" "this" {}

output "account_id" {
  value = data.cloudflare_accounts.this.result[0].id
}

output "account_name" {
  value = data.cloudflare_accounts.this.result[0].name
}
# tests/mock_accounts.tftest.hcl
mock_provider "cloudflare" {
  override_data {
    target = data.cloudflare_accounts.this
    values = {
      result = [
        {
          id         = "fake-account-id-1234"
          name       = "Test Account"
          type       = "standard"
          created_on = "2024-01-01T00:00:00Z"
          managed_by = {
            parent_org_id   = ""
            parent_org_name = ""
          }
          settings = {
            abuse_contact_email = ""
            enforce_twofactor   = false
          }
        },
      ]
    }
  }
}

run "plan_with_mocked_accounts" {
  command = plan

  assert {
    condition     = output.account_id == "fake-account-id-1234"
    error_message = "Expected mocked account ID"
  }

  assert {
    condition     = output.account_name == "Test Account"
    error_message = "Expected mocked account name"
  }
}
$ terraform test
  run "plan_with_mocked_accounts"... fail

│ Error: Failed to compute attribute
│ ...incompatible types; expected object type, found tuple.

Failure! 0 passed, 1 failed.

AWS (PASSES) — same pattern, same Terraform version

The identical override_data pattern works for AWS provider because it uses type-based schema (SDKv2) instead of nested_type:

# main.tf
data "aws_caller_identity" "this" {}
output "account_id" { value = data.aws_caller_identity.this.account_id }
# tests/mock_identity.tftest.hcl
mock_provider "aws" {}

run "plan_with_mocked_identity" {
  command = plan
  override_data {
    target = data.aws_caller_identity.this
    values = { account_id = "123456789012" }
  }
  assert {
    condition     = output.account_id == "123456789012"
    error_message = "Expected mocked AWS account ID"
  }
}
$ terraform test
Success! 1 passed, 0 failed.

Schema difference

The key difference visible in terraform providers schema -json:

  • AWS (works): flat "type": "string" attributes — processed by fillType which handles tuple→list coercion
  • Cloudflare v5 (fails): "nested_type" with "nesting_mode": "list" — processed by fillAttribute which lacks collection handling

Impact

Any provider built entirely with the Plugin Framework that uses ListNestedAttribute, SetNestedAttribute, or MapNestedAttribute will be affected. The Cloudflare v5 provider has 214 data sources with nested_type list attributes and zero with type-based list attributes, making terraform test mocking effectively unusable for it.

Proposed fix

PR: #38370

Move the object type check into NestingSingle/NestingGroup only, and add collection iteration for NestingList/NestingSet/NestingMap that fills each element against the nested attribute schema — matching how fillType already handles this for type-based attributes.

Environment

  • Terraform: v1.11.4, v1.14.3
  • Cloudflare provider: v5.18.0
  • AWS provider: v5.x (control test)
  • OpenTofu: v1.11.5 (not affected)
  • OS: Linux x86_64

This issue was generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugnewnew issue not yet triaged

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions