Terraform

Testing Terraform providers locally

Christoph Thale|
#terraform#development#go

Terraform is one of the most popular tools for Infrastructure-as-Code (IaC), written in the Go programming language.
Out there, you will find countless providers, which have been written by kind people and are available for you to use.
Many of them are also open source, meaning you can contribute and make them even more valuable.

For instance, the azurerm provider for the Azure Cloud is continuously improved by the community. That is pretty cool.
But what if you want to develop and contribute a new feature? How do you ensure that the code you commit is actually working in the end?
The first step should be to test your code locally. How this works, using the example of the azurerm provider, is explained here in this article.

What you need to get started

Before we start, make sure the following prerequisites are met:

  • Go installed: The provider is written and compiled in Go. Install the latest version of Go.
  • Terraform installed: Download Terraform or ensure it is installed (Terraform Download).
  • Basic knowledge of Go and Terraform: Basic experience with both technologies is assumed.
  • MacOS, Windows, or Linux: All relevant operating systems are covered.

Build the provider binary locally

The cool thing about Go is that it allows you to pack all your many lines of code (or those of the provider) into a single executable binary with just one command. How crazy is that?

To do this for our azurerm provider example, navigate to your Terraform provider repository at the level where the main.go file is located. Mostly the root of the project.

Terraform expects an executable file for your provider, the aforementioned binary. The only thing you need to pay attention to is the operating system you are developing on and the CPU architecture of your machine.
This will determine how the following command changes:

GOOS=darwin GOARCH=arm64 go build 

In the following table, you will find an overview of the commands to use:

Operating SystemChipCommand
MacOS (M1/M2/M3)ARM64GOOS=darwin GOARCH=arm64 go build
MacOS (Intel)AMD64GOOS=darwin GOARCH=amd64 go build
Windows (Intel/AMD)AMD64GOOS=windows GOARCH=amd64 go build
Linux (Intel/AMD)AMD64GOOS=linux GOARCH=amd64 go build
Linux (ARM64)ARM64GOOS=linux GOARCH=arm64 go build

The binary should now be in the directory. It will be named terraform-provider-azurerm and will be located in the folder where you ran the command.
The azurerm part of the name will vary depending on the provider you are working with.

Since I work with multiple providers locally and like to keep my binaries organized for later use,
I’ve created a folder on my machine where I store all my compiled provider binaries. For example: /Users/christoph/go/bin

Now that we have the provider binary, we can start using it.

Configure the Terraform CLI configuration file

One last thing needs to be configured. How does Terraform know that, in your newly set up test project
(i.e., the project where you want to test your newly implemented code), it should use your locally built binary
instead of downloading the provider from the registry (which does not yet contain your code)?

Terraform allows you to test local provider binaries via the dev_overrides configuration.
To use this, we need to create (or edit, if it already exists) a Terraform CLI configuration file on our machine.

The file is located at:

  • macOS/Linux: ~/.terraformrc
  • Windows: %APPDATA%\terraform.rc

Add the following configuration (in our case):

provider_installation {
  dev_overrides {
    "registry.terraform.io/hashicorp/azurerm" = "/Users/christoph/go/bin"
  }
  direct {}
}

Terraform is smart enough to locate the terraform-provider-azurerm binary in the folder where you placed the binary you built earlier.

Now you can define the provider in your test project as usual in your provider.tf file:

terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = "4.14.0"
    }
  }
  backend "local" {
    
  }
}

provider "azurerm" {
  (...)
  features {}
}

and Terraform will recognize that you have specified a dev_overrides configuration in your Terraform CLI configuration file (~/.terraformrc).
As a result, it will use your local version of the provider.

Once you run a terraform plan, you should see something like this:

img not found

One last note

If you are seriously considering contributing to the azurerm provider, please check out the developer and contribution guides.

Common Errors

exec format error

This error occurs if the binary was built for the wrong architecture. Double-check your go build command.

Provider not found

This error occurs if the dev_overrides in the Terraform CLI configuration file is misconfigured or contains incorrect paths.

That is all for now. Write lots of code, and I will see you in the next article.

Back to Blog