Building a Pet Store Terraform Provider
Understand how to create custom resources to publish through the Terraform provider registry.
Even though the Terraform provider registry has almost every provider we can think of, there is a chance that a provider we need does not yet exist. Perhaps we want to use Terraform to interact with resources of a proprietary API internal to our company. If we want to manage resources that don't yet exist in the Terraform provider ecosystem, we will need to write a provider for that API. The good news is that writing a Terraform provider is relatively simple. The thoughtful folks at HashiCorp provide great documentation, SDKs, and tools to make building a provider a breeze.
In this lesson, we will learn how to build our own provider. The Terraform provider we are building in this lesson will expose pet resources and will interact with a local docker-compose hosted
pet store service to simulate an external API.
We will learn how to define custom resources with strong schema and validations, create data sources, and implement CRUD interactions for our pet resources. Finally, we’ll discuss publishing a module for the world to use via the Terraform provider registry.
Resources for building custom providers
HashiCorp provides an extensive set of tutorials for building custom providers. We highly recommend reviewing the content if you intend to build your own custom provider.
We will not cover all of the code, but we will dive into the most interesting parts. We've done my best to keep to only the most simple implementation; however, simple is not always elegant.
Additionally, our pet store custom provider uses the Terraform plugin SDK v2 rather than the new (at the time of writing) Terraform plugin framework. We chose this path as the majority of existing providers use the SDK v2, and the Terraform plugin framework has not reached stability yet. If you are interested in weighing the benefits, read the “Which SDK Should I Use?” article from HashiCorp.
Now that we have established a foundation of content and learning, let's proceed to the code.
The pet store provider
Our pet store Terraform provider is just another Go application. Most of the interactions between Terraform and the provider are handled at the Terraform SDK level, and very little gets in the way of the provider developer. Let's start off by taking a look at the directory structure of the provider:
It's a standard Go application with an entry point in main.go
. Let's start at the top and work our way down the files. The first on the list is the Makefile
:
HOSTNAME=example.comNAMESPACE=gofordevopsNAME=petstoreBINARY=terraform-provider-${NAME}VERSION=0.1.0GOARCH := $(shell go env GOARCH)GOOS := $(shell go env GOOS)default: installbuild:go build -o ${BINARY}install: buildmkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${GOOS}_${GOARCH}mv ${BINARY} ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${GOOS}_${GOARCH}test:go test ./... -vtestacc:TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
The preceding Makefile
offers some helpful build tasks and environmental configuration. For example, make
or make install
will build the provider for the current architecture and place it in the ~/.terraform.d/plugins
directory tree, which will enable us to use the provider locally without publishing it to the registry.
Next, we have the docker-compose.yml
...