Description
terraform-plugin-go version
v0.14.3
Relevant provider source code
// this is making a panic, not even getting to an error
values, err := req.Config.Unmarshal(tftypes.Object{
// objTypeDef.AttributeTypes is the result of calling ValueType() on a tfprotov5.Schema
AttributeTypes: objTypeDef.AttributeTypes
})
// this is the tfprotov5 schema
tfprotov5.Schema{
Version: 1,
Block: &tfprotov5.SchemaBlock{
Version: 1,
Attributes: []*tfprotov5.SchemaAttribute{
{
Name: "id",
Type: tftypes.String,
Computed: true,
},
{
Name: "regular_attribute",
Type: tftypes.String,
Optional: true,
},
{
Name: "dynamic_attribute",
Type: tftypes.DynamicPseudoType,
Optional: true,
},
},
BlockTypes: []*tfprotov5.SchemaNestedBlock{
{
TypeName: "dynamic_block",
Nesting: tfprotov5.SchemaNestedBlockNestingModeList,
Block: &tfprotov5.SchemaBlock{
Attributes: []*tfprotov5.SchemaAttribute{
{
Name: "bar",
Type: tftypes.DynamicPseudoType,
Optional: true,
},
{
Name: "foo",
Type: tftypes.Number,
Optional: true,
},
},
},
},
{
TypeName: "regular_block",
Nesting: tfprotov5.SchemaNestedBlockNestingModeList,
Block: &tfprotov5.SchemaBlock{
Attributes: []*tfprotov5.SchemaAttribute{
{
Name: "bar",
Type: tftypes.String,
Optional: true,
},
{
Name: "foo",
Type: tftypes.Number,
Optional: true,
},
},
},
},
},
},
}
Terraform Configuration Files
data "provider_dummy" "test" {
dynamic_attribute = "hello"
regular_attribute = "bye"
regular_block {
bar = "bar"
foo = 3
}
dynamic_block {
bar = "bar"
foo = 4
}
}
Expected Behavior
it should be able to create a statefile, this behavior is happening if your remove the DPT of the dynamic_block
schema and change it to a string, (tftypes.String
instead of tftypes.DynamicPseudoType
)
Actual Behavior
A panic is produced
2023-02-28T17:19:19.961-0600 [ERROR] sdk.proto: Error from downstream: tf_proto_version=5.3 tf_rpc=ReadDataSource tf_data_source_type=provider_dummy tf_req_id=4939bb6e-c465-28c6-470f-5a42012f85e4 error="Cant unmarshall config input, AttributeName(\"dynamic_block\").ElementKeyInt(0): error decoding object length: msgpack: invalid code=c4 decoding map length" tf_provider_addr=registry.terraform.io/hashicorp/provider
provider_low_example/internal/data_dummy/dummy_data_test.go:21: Step 1/1 error: Error running pre-apply refresh: exit status 1
Error: Plugin error
with data.provider_dummy.test,
on terraform_plugin_test.tf line 3, in data "provider_dummy" "test":
3: data "provider_dummy" "test" {
The plugin returned an unexpected error from
plugin.(*GRPCProvider).ReadDataSource: rpc error: code = Unknown desc = Cant
unmarshall config input, AttributeName("dynamic_block").ElementKeyInt(0):
error decoding object length: msgpack: invalid code=c4 decoding map length
Steps to Reproduce
Run the following test
References
Inspecting with the debugger I found the following:
-
Changing the nesting mode in the block attributes changes the behavior of the types
- set won't accept dynamic pseudotypes
- list accept them, but the lib that is unmarshalling the bytes from the RCP (github.com/vmihailenco/msgpack/v4) is having problems reading the decoded state
- it is raising a panic because it cant parse the hex value of 0xC4, which is what is passing the length value of the list
fail decoding,testName: decoded_with_dpt_block error -> AttributeName("dynamic_block"): error decoding object length: msgpack: invalid code=92 decoding map length
-
When the terraform core code is reached, there is a conversion from the schema to a cty.Value, if a block contains a DPT it will change the whole root attribute of the block to a DTP instead of changing the local attribute, https://github.com/hashicorp/terraform-plugin-sdk/blob/main/internal/configs/configschema/implied_type.go#L40
-
Also this is the code that is not allowing DPT in sets, https://github.com/hashicorp/terraform-plugin-sdk/blob/main/internal/configs/configschema/implied_type.go#L47
-
Once the cty value reaches to
objchange
in theterraform plan
time, it panics because the cty.object was transformed to a cty.dynamicPseudoType in the above step https://github.com/hashicorp/terraform/blob/main/internal/plans/objchange/objchange.go#L71