Specifiy Terraform plugin protocol version when using TF_REATTACH_PROVIDERS

Hello. :slight_smile:

I am going to implement a Terraform Plugin SDK written in C#, but I am facing problem when debugging a Terraform plugin.

So, can someone of you tell me how I can tell Terraform to use a specific protocol version when using TF_REATTACH_PROVIDERS?? The plugin protocol version 5.3 is working, but I also would like to test it against the plugin protocol version 6.3. Sadly Terraform states that my grpc server does not implement GetProviderSchema:

Error: failed to read schema for debug_init.default in registry.terraform.io/pseudo-dynamic/debug: failed to retrieve schema from provider "registry.terraform.io/pseudo-dynamic/debug": Unsupported plugin method: The plugin.(*GRPCProvider).GetProviderSchema method is not supported by this plugin

What’s strange too is that the name in the error message is “GetProviderSchema” and not “GetSchema” because “GetProviderSchema” is the gRPC method implement in plugin protocol version 6.3, but this is the protocol version that does not seem to work.

I specfiy “TF_REATTACH_PROVIDERS” takem from Plugin Development - Debugging Providers | Terraform by HashiCorp as following (formatted for better clarity):

{
    "registry.terraform.io/pseudo-dynamic/debug": {
        "Protocol": "grpc",
        "Pid": 17940,
        "Test": true,
        "Addr": {
            "Network": "tcp",
            "String": "127.0.0.1:50727"
        }
    }
}

I am using Terraform v1.2.8. Maybe I need to upgrade?

Kind regards,
Teneko

Hi @teneko :wave: Thank you for raising this.

The protocol version for Go-based Terraform plugins is handled by the GitHub - hashicorp/go-plugin: Golang plugin system over RPC. module and in particular the handshake configuration: plugin package - github.com/hashicorp/go-plugin - Go Packages

Each of the higher level SDKs (terraform-plugin-sdk and terraform-plugin-framework) nowadays both use terraform-plugin-go’s lower level server packages to manage protocol version 5 versus 6, for example: terraform-plugin-go/server.go at c199d46e5e81af6c102a1c5e7aaaa838f0484d8c · hashicorp/terraform-plugin-go · GitHub

The TF_REATTACH_PROVIDERS configuration is only intended to “connect” Terraform CLI to provider server(s), while the implementation details of the connection, once made, are managed by go-plugin in that case. Maybe a good analogy in this case is the OSI model where the reattach configuration is a detail of the transport layer and the protocol version is a detail of the application layer.

Hope this helps!

Ahh I see. Yes this analogy helps to understand the architecture, but to be honest, this does not help to solve the actual problem.

You were absolutely correct, that the client needs to know at least the handshake information to connect. This can be either the process stdout or the TF_REATTACH_PROVIDERS environment variable approach, depending on whether the plugin server is started by Terraform or not. What I didn’t know is, that my TF_REATTACH_PROVIDERS environment variable was not complete. By looking at this code line terraform-plugin-go/server.go at 31394abee4612e75fa60d30615445d126f3a1c79 · hashicorp/terraform-plugin-go · GitHub for example, we can see that the ProtocolVersion is missing. By setting it and of course switching to the gRPC implementation of protocol v6 it does work. The TF_REATTACH_PROVIDERS environment variable should look now like this (formatted for better clarity):

{
    "registry.terraform.io/pseudo-dynamic/debug": {
        "Protocol": "grpc",
        "ProtocolVersion": 6,
        "Pid": 24820,
        "Test": true,
        "Addr": {
            "Network": "tcp",
            "String": "127.0.0.1:64602"
        }
    }
}