Write Your First Terraform Provider ✨

Shaked Braimok Yosef
3 min readMay 7, 2024

Terraform is a popular Infrastructure as Code (IaC) tool that allows you to define and manage cloud infrastructure using declarative configuration files. While Terraform offers a variety of built-in providers for interacting with cloud platforms and services, you might encounter scenarios where you need a custom provider to integrate with a specialized system. This guide will walk you through building your first Terraform provider from scratch.

Understanding Terraform Providers

Terraform providers are the interface between Terraform configurations and external services. They define resources and data sources, enabling Terraform to manage a wide range of infrastructure components, from cloud instances to databases. When existing providers don’t cover your needs, creating a custom provider allows you to define your own resources and interact with unique services.

Prerequisites

Before creating a custom Terraform provider, make sure you have the following:

  • Basic knowledge of Terraform and Infrastructure as Code (IaC).
  • Familiarity with the Go programming language.
  • Terraform CLI installed: Download from the Terraform website.
  • Go installed: Get the latest version from the official Go website. Ensure your environment variables (like GOROOT and GOPATH) are set up.

Writing Provider Code

Start by creating a Go module for your Terraform provider and defining the core structure.

If you’d prefer to use a template instead of starting from scratch, Hashicorp has already created one.

Provider Initialization

This is where you define your provider schema and resources. Create a file called provider.go:

package myprovider

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

// Provider initializes the Terraform provider with its schema and resources.
func Provider() *schema.Provider {
return &schema.Provider{
Schema: map[string]*schema.Schema{
"api_key": {
Type: schema.TypeString,
Required: true,
},
},
ResourcesMap: map[string]*schema.Resource{
"example_resource": resourceExample(),
},
ConfigureFunc: configureProvider,
}
}

// configureProvider sets up the provider's client with its configuration.
func configureProvider(d *schema.ResourceData) (interface{}, error) {
apiKey := d.Get("api_key").(string)
// Initialize your service client with the API key
client := &Client{APIKey: apiKey}
return client, nil
}

Define a Resource

Next, define the schema and CRUD operations for a simple resource. In the same directory, create a new file, resource_example.go:

func resourceExample() *schema.Resource {
return &schema.Resource{
Create: resourceExampleCreate,
Read: resourceExampleRead,
Update: resourceExampleUpdate,
Delete: resourceExampleDelete,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
},
}
}

func resourceExampleCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Client)
// Create your resource in the external system
resourceID := "generated-id" // Simulate resource creation
d.SetId(resourceID)
return nil
}

func resourceExampleRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Client)
// Read your resource from the external system
// Simulate reading
return nil
}

func resourceExampleUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Client)
// Update your resource in the external system
return nil
}

func resourceExampleDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Client)
// Delete your resource from the external system
return nil
}

Testing Your Provider

After writing the code, test your provider with a simple Terraform configuration to ensure it works as expected. Create a Terraform configuration file:

provider "myprovider" {
api_key = "my-api-key"
}

resource "myprovider_example_resource" "example" {
name = "Test Resource"
}

To test, run the following commands in your Terraform configuration directory:

terraform init
terraform apply

If successful, your provider should create the specified resource without errors.

Take It Further

Creating a basic Terraform provider involves defining the provider schema, implementing resource CRUD operations, and testing the provider with a simple Terraform configuration. With this guide, you should have a good starting point for building and testing your first Terraform provider.

Good luck, and happy coding! 🚀 Learn more here: https://senora.dev

--

--

Shaked Braimok Yosef

Developer Platforms Builder · DevOps Consultant · Tech Content Creator