pulumi / pulumi-terraform-bridge

A library allowing Terraform providers to be bridged into Pulumi.
Apache License 2.0
194 stars 43 forks source link

Cannot use lists of empty objects in cross-tests #2365

Open VenelinMartinov opened 3 weeks ago

VenelinMartinov commented 3 weeks ago

What happened?

Due to a limitation in https://github.com/hashicorp/terraform-plugin-go, tftypes can not represent types with empty objects, like list of empty object.

This is due to https://github.com/hashicorp/terraform-plugin-go/blob/2749aa5cd6408d893abbb38c5ace1fb7d8b7c522/tftypes/object.go#L76

... 
    if v.AttributeTypes == nil || o.AttributeTypes == nil {
        // when doing exact comparisons, we can't compare types that
        // don't have attribute types set, so we just consider them not
        // equal
        return false
    }
...

This prevents us from testing useful things in cross-tests, like testing collection-only diffs: https://github.com/pulumi/pulumi-terraform-bridge/blob/4c5493a410cb50563cd22fdfe0b6a95112c00c72/pkg/tfbridge/diff_test.go#L2125

We should consider forking the library for use in cross-tests. We can use it with a different name to limit the scope of its usage to just the assertion code.

Example

tftypes.NewValue(
    tftypes.List{ElementType: tftypes.Object{}},
    []tftypes.Value{
        tftypes.NewValue(
            tftypes.Object{},
            map[string]tftypes.Value{},
        ),
    },
)

Output of pulumi about

.

Additional context

No response

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

VenelinMartinov commented 3 weeks ago

Found a workaround for the case I need:

t1 := tftypes.Object{
    AttributeTypes: map[string]tftypes.Type{
        "prefix": tftypes.String,
    },
}

tftypes.NewValue(
    tftypes.List{ElementType: t1},
    []tftypes.Value{
        tftypes.NewValue(
            t1,
            map[string]tftypes.Value{
                "prefix": tftypes.NewValue(tftypes.String, nil),
            },
        ),
    },
),

Specifying an explicit null for any property of the object is equivalent in HCL to an empty object.

It does change the generated HCL and the null/empty distinction could be meaningful in pulumi but it's good enough for now.

rule {
  filter {
    prefix = null
  }
}

vs

rule {
  filter {
  }
}