Sobes.tech
Senior

How to develop your own provider in Terraform?

sobes.tech AI

Answer from AI

To develop your own Terraform provider, you need to:

  1. Choose a language: Go - the primary language for Terraform providers.

  2. Install SDK: Go and Terraform Plugin SDK.

  3. Create a project structure:

    # Create base files
    mkdir terraform-provider-myprovider
    cd terraform-provider-myprovider
    go mod init github.com/myorg/terraform-provider-myprovider
    go get github.com/hashicorp/terraform-plugin-sdk/v2
    
  4. Implement the provider: create a provider.go file and define the Provider structure, including:

    • Schema: defining provider configuration parameters.
    • ResourcesMap: mapping resource names to their implementations.
    • DataSourcesMap: mapping data source names to their implementations.
    package main
    
    import (
    	"context"
    
    	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
    	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
    )
    
    func Provider() *schema.Provider {
    	return &schema.Provider{
    		Schema: map[string]*schema.Schema{
    			"endpoint": { // Example provider configuration parameter
    				Type:        schema.TypeString,
    				Optional:    true,
    				DefaultFunc: schema.EnvDefaultFunc("MYPROVIDER_ENDPOINT", nil),
    			},
    		},
    		ResourcesMap: map[string]*schema.Resource{
    			"myprovider_resource": resourceMyProviderResource(), // Resource implementation
    		},
    		DataSourcesMap: map[string]*schema.Resource{
    			// Data sources implementation
    		},
    		ConfigureContextFunc: providerConfigure, // Client setup function
    	}
    }
    
    func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
    	// Provider client setup logic
    	return nil, nil
    }
    
    func main() {
    	// Entry point
    }
    
  5. Implement resources and data sources: create separate files for each resource and data source (e.g., resource_myprovider_resource.go). Each resource should implement functions:

    • Schema: resource parameter definitions.
    • Create: create resource.
    • Read: read resource state.
    • Update: update resource.
    • Delete: delete resource.
    • Exists: check resource existence (optional).
    package main
    
    import (
        "context"
    
        "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
        "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
    )
    
    func resourceMyProviderResource() *schema.Resource {
        return &schema.Resource{
            CreateContext: resourceMyProviderResourceCreate,
            ReadContext:   resourceMyProviderResourceRead,
            UpdateContext: resourceMyProviderResourceUpdate,
            DeleteContext: resourceMyProviderResourceDelete,
            Schema: map[string]*schema.Schema{
                "name": { // Example resource parameter
                    Type:     schema.TypeString,
                    Required: true,
                },
            },
        }
    }
    
    func resourceMyProviderResourceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
        // Resource creation logic
        return nil
    }
    // ... Implement Read, Update, Delete
    
  6. Compile: build the provider executable.

  7. Install: place the compiled binary in the Terraform plugins directory (~/.terraform.d/plugins/ or another location specified in Terraform configuration).

  8. Test: write Acceptance Tests to verify the provider's correctness.

Additional steps may include:

  • Document the provider.
  • Publish the provider to Terraform Registry.
  • Use a framework instead of SDK for more modern development.