Skip to content

Can't mock cloudflare_rulesets datasource in Terraform test #6387

@anthonydurot

Description

@anthonydurot

Confirmation

  • This is a bug with an existing resource and is not a feature request or enhancement. Feature requests should be submitted with Cloudflare Support or your account team.
  • I have searched the issue tracker and my issue isn't already found.
  • I have replicated my issue using the latest version of the provider and it is still present.

Terraform and Cloudflare provider version

terraform -v
Terraform v1.13.3
on darwin_arm64
+ provider registry.terraform.io/cloudflare/cloudflare v5.10.1

Affected resource(s)

data.cloudflare_rulesets

Terraform configuration files

# main.tf
terraform {
  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "5.10.1" # Not 5.11.0 because it lacks the darwin_arm64 binary it seems
    }
  }
}

provider "cloudflare" {
  api_token = "api_token"
}

data "cloudflare_rulesets" "zone_rulesets" {
  zone_id = var.zone_id
}


variable "zone_id" {
    type = string
}


# test.tftests.hcl

mock_provider "cloudflare" {
  override_during = plan
  override_data {
    target = data.cloudflare_rulesets.zone_rulesets
    override_during = plan
    values = {
      result = [{
        description = "Created by the Cloudflare security team, this ruleset provides normalization on the URL path"
        id = "70339d97bdb34195bbf054b1ebe81f76"
        kind = "managed"
        name = "Cloudflare Normalization Ruleset"
        phase = "http_request_sanitize"
      }]
    }
  }
}

run "valid_cloudflare" {

  command = plan
  
  variables {
    zone_id = "11111111111111111111111111111111"
  }

  assert {
    condition     = data.cloudflare_rulesets.zone_rulesets.result[0].id == "70339d97bdb34195bbf054b1ebe81f76"
    error_message = "Cloudflare Ruleset ID does not match expected value"
  }


}

Link to debug output

https://gist.github.com/anthonydurot/b6002e097e3ee71f07bd0c0c89b2d18b

Panic output

No response

Expected output

test.tftest.hcl... in progress
  run "valid_cloudflare"... pass
test.tftest.hcl... tearing down
test.tftest.hcl... pass

Success! 1 passed, 0 failed.

Actual output

test.tftest.hcl... in progress
  run "valid_cloudflare"... fail

│ Error: Failed to compute attribute

│   with data.cloudflare_rulesets.zone_rulesets,
│   on main.tf line 14, in data "cloudflare_rulesets" "zone_rulesets":
│   14: data "cloudflare_rulesets" "zone_rulesets" {

│ Terraform could not compute a value for the target type set of object with the mocked data defined at test.tftest.hcl:5,3-16 with the attribute ".result":
│ incompatible types; expected object type, found tuple.

test.tftest.hcl... tearing down
test.tftest.hcl... fail

Failure! 0 passed, 1 failed.

Steps to reproduce

Create both main.tf and test.tftest.hcl file in an empty directory. Then run a terraform init && terraform test

Additional factoids

I think the issue is linked to how the type of this datasource is implemented. For exemple let's change the test as such:

mock_provider "cloudflare" {
  override_during = plan
  override_data {
    target = data.cloudflare_rulesets.zone_rulesets
    override_during = plan
    values = {
      result = {}
    }
  }
}

run "valid_cloudflare" {

  command = plan
  
  variables {
    zone_id = "11111111111111111111111111111111"
  }

  assert {
    condition     = data.cloudflare_rulesets.zone_rulesets.result == {}
    error_message = "Cloudflare Ruleset ID does not match expected value"
  }


}

You will get an error:

Error: Test assertion failed
│ 
│   on test.tftest.hcl line 23, in run "valid_cloudflare":
│   23:     condition     = data.cloudflare_rulesets.zone_rulesets.result == {}
│     ├────────────────
│     │ Warning: LHS and RHS values are of different types
│     │ Diff:
│     │ --- actual
│     │ +++ expected
│     │ - []
│     │ + {}
│ 
│ 
│ Cloudflare Ruleset ID does not match expected value
╵

test.tftest.hcl... tearing down
test.tftest.hcl... fail

Failure! 0 passed, 1 failed.

This means that result must be an object, but it must act as a set.

In the code we see that result is of type customfield.NestedObjectSet[RulesetsRulesetDataSourceModel], it's not a primitive Terraform type, and there is conversion utility functions. But those functions are not called when performing tests.

References

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.version/5Categorizes issue or PR as related to version 5 of the provider.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions