paint-brush
My Path for Terraform Provider Creationby@nmishin
341 reads
341 reads

My Path for Terraform Provider Creation

by Nikolai MishinMarch 14th, 2024
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

In this article, I want to share my experience of creating a terraform provider from scratch, and provide some useful links and tips.
featured image - My Path for Terraform Provider Creation
Nikolai Mishin HackerNoon profile picture


In this article, I want to share my experience of creating a terraform provider from scratch, show how to add it to the Terraform and OpenTofu registries, and share some useful links and tips.


I wrote the provider for Dodo pizza, and I was inspired by Terraform Dominos Pizza provider. Instead of Dominos, Dodo pizza doesn't allow you to create an order via API - only retrieving some data, but for learning purposes, this is more than enough.

Which SDK to use?

First of all, you need to decide which HashiCorp SDK you will use. For today HashiCorp offers 2 Go programming language Software Development Kits (SDKs) for building Terraform providers: Terraform Plugin Framework and SDKv2. For newly created providers they recommend using the framework, and for existing providers to migrate from SDKv2 to the framework. The Terraform Plugin Framework  “offers significant advantages as compared to the SDKv2”, as HashiCorp says. I decided to use the old, good SDKv2 for two reasons: almost all examples and existing providers that I know are using SDKv2, and it will be interesting for me to understand how to migrate from SDKv2 to the new framework.

How to interact with API?

All articles that I found provide examples of limited sample APIs or include API calls inside the provider itself. But all “large” providers use Go libraries to interact with existing API. For example, Cloudflare provider uses their own cloudflare-go, and GitHub provider uses go-github library maintained by Google. And I decided to do the same - create my own library and use it in the provider.


Dodo Global API uses swagger, which is such a widely used tool, that I believe it should have some library generator for it. I started to google it and found an article about swagger-codegen - the standard way to generate client SDK for swagger.


In my case, I used only one command to generate an almost fully functional client SDK for Dodo API:

swagger-codegen generate -i https://globalapi.dodopizza.com/api/swagger/v2/swagger.json -l go -o .


You can find dodo-go here: https://github.com/Nmishin/dodo-go

How to start writing the provider?

I found several articles about terraform provider creation, from HashiCorp and independent writers:

I realized that some terraform providers use API libraries very similar to my generated dodo-go library, and it was super helpful to compare my provider with existing provider, for example: terraform-provider-authentik.


Cloudflare terraform provider also can be a good example, since it’s well maintained and not as complicated as, for example, terraform-provider-aws.

What to do next after creating the provider?

When your provider is ready, or you are happy with existing functionalities, you need to publish it to the Terraform registry and OpenTofu registry if you plan to use it with opentofu.


All the needed steps are well described in HashiCorp’s documentation:

https://developer.hashicorp.com/terraform/registry/providers/publishing#terraform-registry-manifest-file


And this article from Kevin Wang can be useful as well:
https://thekevinwang.com/2023/10/05/build-publish-terraform-provider


After publishing provider to the Terraform registry, publishing to OpenTofu will be much easier, because you have already done all the necessary presteps.

You need to create two issues: the first one is the provider itself, and second one is about the provider’s GPG Key.


Example of adding provider: https://github.com/opentofu/registry/issues/228

Example of adding GPG Key:https://github.com/opentofu/registry/issues/230


And that's it!

After your provider is added to all registries, you can add it to the config as any regular provider.

Let’s check how it works for my terraform-provider-dodo.

In my test configuration, I have three files and I want to retrieve data about available brands:

cat provider.tf 

terraform {
  required_providers {
    dodo = {
      source = "Nmishin/dodo"
      version = "0.0.1"
    }
  }
}

provider "dodo" {}


cat main.tf 

data "dodo_brand" "test" {}


cat outputs.tf 

output "brands" {
  value = data.dodo_brand.test.names
}


tofu plan

data.dodo_brand.test: Reading...
data.dodo_brand.test: Read complete after 1s [id=bf4b2096fab07279e4a6a9db5fb704b5]

Changes to Outputs:
  + brands = [
      + "dodopizza",
      + "doner42",
      + "drinkit",
    ]

You can apply this plan to save these new output values to the OpenTofu state, without changing any real infrastructure.

Conclusion

Right now everyone with basic programming skills and terraform/opentofu experience can create its own provider. There is so much information about how to start to write code and publish provider, but in this article I wanted to provide high level instruction with good useful links. And I hope my story will help you not to be afraid to start creating a provider from scratch and I am absolutely sure that you will be successful with it!