Free — no signup required

The Protocol: gRPC and go-plugin

2 min read

How Core and Plugins Communicate

The communication channel between Core and Plugins is gRPC (Google Remote Procedure Call) — a high-performance, binary protocol built on top of HTTP/2. gRPC uses Protocol Buffers (protobuf) to define the message format, which means both sides agree on a strict schema for every call. This is what makes the plugin system stable across versions.

The full lifecycle of a plugin connection looks like this:

  1. Spawn: Core starts the plugin binary as a child process.
  2. Handshake: The plugin writes a magic handshake string to stdout — something like 1|5|tcp|127.0.0.1:12345|grpc. This tells Core: "I am a Terraform plugin, protocol version 5, listening on localhost port 12345 via gRPC."
  3. Connect: Core opens a gRPC connection to that local address.
  4. RPC Calls: Core makes structured remote procedure calls to the plugin:
  5. GetProviderSchema — "Tell me what resources and data sources you support."
  6. ValidateResourceConfig — "The user wrote this HCL. Is it valid?"
  7. PlanResourceChange — "Here is the old state and the new config. What will change?"
  8. ApplyResourceChange — "Execute the change and return the new state."

This architecture is powered by HashiCorp's open-source go-plugin library. Its key properties are:

  • Crash isolation: If a plugin panics, Core catches the process exit and reports a clean error instead of crashing itself.
  • Language agnosticism: Any language that can implement the gRPC interface can be a provider. In practice, Go is the de-facto standard because the SDK and Framework are written in Go.
  • Versioned protocol: The handshake includes a protocol version number, allowing Core and plugins to negotiate compatibility.

The go-plugin library also handles mTLS (mutual TLS) automatically for the local gRPC connection, preventing other processes on the same machine from injecting malicious responses into the plugin channel. This is a subtle but important security detail — even though the connection is localhost-only, it is still authenticated and encrypted.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free