How count.index works

I develop a provider, and got the next error when I was trying to define the next configuration

locals {
  test = [{
    rule_type : "includes"
    names : ["-dev"]
  }]
}

resource "coralogix_tco_policy_logs" "tco_policy" {
  count = 1

  name        = "test"
  priority     = "medium"
  order        = count.index + 1
  severities   = ["debug", "verbose", "info", "error", "warning", "critical"]
  applications = local.test[count.index] # gives error
#  applications = local.test[0]                 # works
}

When I run plan, I get the next error

│ Error: Value Conversion Error
│
│ with coralogix_tco_policy_logs.tco_policy,
│ on coralogix_tco.tf line 118, in resource "coralogix_tco_policy_logs" "tco_policy":
│ 118: applications = local.test[count.index]
│
│ An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:
│
│ Received unknown value, however the target type cannot handle unknown values. Use the corresponding types package type or a custom type that handles unknown values.
│
│ Path: applications
│ Target Type: *coralogix.TCORuleModel
│ Suggested Type: basetypes.ObjectValue

But the same config works well with applications = local.test[0].
I wonder, what’s the difference between count.index and having hardcoded value that can cause this failure?

Hey there @OrNovo :wave: thanks for posting and sorry you’re running into trouble here,

Addressing the error

Based on that error message, I’m assuming that you have a data model that looks something like:

type ResourceModel struct {
	// other `tfsdk` fields
	Applications       *coralogix.TCORuleModel `tfsdk:"applications"`
}

type TCORuleModel struct {
	// other `tfsdk` fields
}

The error you’re running into is a result of Go structs not having a concept of Unknown, so when plugin framework receives an Unknown value from Terraform core, it returns a diagnostic because it can’t convert Unknown into the TCORuleModel struct. The fix would be to switch to the plugin framework types.Object type:

type ResourceModel struct {
	// other `tfsdk` fields
	Applications        types.Object `tfsdk:"applications"`
}

type TCORuleModel struct {
	// other `tfsdk` fields
}

You can see some examples of accessing/setting types.Object values in our recently revamped documentation:

Terraform Core behavior

I don’t have a background on why Terraform core considers the local.test[count.index] expression as unknown, regardless, our recommendation is to always use the built-in framework types to stay in-line with Terraforms type system concepts.

Perhaps @jbardin or someone from the Terraform core team could expand on why that expression is unknown.

1 Like

You must be able to deal with unknown in every attribute set via the configuration. Anything not given a static literal in the configuration could be unknown at some point. The static validation happens before any planning, with all input variables and expansion values as unknown, so that the configuration can be validated against all possible inputs and completely offline.

In this case you are seeing that count and each objects are also unknown during the initial validation, because there are not any individual instances to validate.

1 Like