Free — no signup required

Debugging Providers

2 min read

The Black Box Problem

Since plugins run as background processes managed by Terraform Core, standard debugging techniques don't work out of the box. If you add fmt.Println("debug: here") to your provider code, the output is captured by the IPC channel and never reaches your terminal.

Approach 1: Structured Logging with tflog

The Plugin Framework provides a context-aware logging package that integrates with Terraform's log output system:

import "github.com/hashicorp/terraform-plugin-log/tflog"

func (r *serverResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
    // Structured key-value pairs are searchable in log output
    tflog.Debug(ctx, "Creating server", map[string]interface{}{
        "name":   plan.Name.ValueString(),
        "region": plan.Region.ValueString(),
    })

    // After the API call:
    tflog.Info(ctx, "Server created successfully", map[string]interface{}{
        "id": apiResp.ID,
    })
}

These logs surface through an environment variable set before running Terraform, which can be scoped to show every log level, filtered down to just the provider's own output, or redirected to a file instead of the terminal.

Approach 2: Interactive Debugging with Delve

For complex bugs where you need to set breakpoints and inspect variables, you can attach a Go debugger (Delve) to your running provider. This is called reattach mode: the provider binary is built with debug symbols and started directly in a debug mode, at which point it prints a connection string identifying its running process. Exporting that string as an environment variable in a separate terminal and then running Terraform there causes Terraform Core to connect to the already-running provider process instead of spawning a new one — so breakpoints set in Delve get hit as terraform apply actually executes.

Approach 3: Terraform Provider Logs in CI

In CI pipelines, always set TF_LOG=INFO at minimum and redirect to a file. When a provider test fails in CI, the log file is the first place to look. Store it as a CI artifact so it survives after the job completes.

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