Enable Go CPU profiling for Terraform

Dainius Šerplis | Feb 12, 2023 min read

Enable Go profiler for Terraform

When developing providers, there might be cases when something odd is happening - i.e. Terraform behaves slowly and Go CPU profiling can help.

Not an everyday task, but might unnecessarily burn time when needed.

  1. Clone Terraform repository
git@github.com:hashicorp/terraform.git
  1. Checkout your desired version
git checkout v1.3.7
  1. Patch the code

Open up main.go and look for function realMain (line similar to func realMain() int {).

At the top of the function, paste the following snippet:

pidInt := os.Getpid()
f, perr := os.Create(fmt.Sprintf("%d-terraform-cpu.pprof", pidInt))
if perr != nil {
        fmt.Println("could not create CPU profile: ", perr)
        os.Exit(1)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()

The final result should look similar to this:

func realMain() int {
  // Enable CPU profiling
  pidInt := os.Getpid()
  f, perr := os.Create(fmt.Sprintf("%d-terraform-cpu.pprof", pidInt))
  if perr != nil {
          fmt.Println("could not create CPU profile: ", perr)
          os.Exit(1)
  }
  pprof.StartCPUProfile(f)
  defer pprof.StopCPUProfile()
  // End of Enable CPU profiling
  
  // default Terraform code from here...
  defer logging.PanicHandler()

  var err error
  ....

Note. Depending on the editor you might need to run `go mod tidy

  1. Build the binary
go build -o terraform
  1. Profile !

Whenever executing the terraform file, it will produce files named 36980-terraform-cpu.pprof. The first number will be pid of terraform process when it is run. This prevents overwriting the profile when executing it multiple times.

Profiling using pprof is another story.