Table of Content
- Introduction
- Bit of intro into Terraform
- Terraform Provider
- Terraform Custom Provider
- What is required to develop Custom Provider
- Install and Configure Terraform
- How to develop provider code with Go
- Bibliography and Reference
Introduction
We assume that the readers of this article has prior understanding and working knowledge in Terraform and has created resource provisioning TF files for various Cloud providers. But still....
Bit of intro into Terraform
- Terraform is a Cloud agnostic Infra as code technology and used to create immutable infrastructure.
- Terraform is used to create, manage, and update infrastructure resources such as physical machines, VMs, network switches, containers, and more. Almost any infrastructure type can be represented as a resource in Terraform.
- Deliver infrastructure as code with Terraform using declarative tf configuration files
- Plan and predict changes: Terraform provides an elegant user experience for operators to safely and predictably make changes to infrastructure
- Create reproducible infrastructure: Terraform makes it easy to re-use configurations for similar infrastructure, helping you avoid mistakes and save time.
Terraform Provider
A provider is responsible for understanding API interactions and exposing resources. Most providers configure a specific infrastructure platform (either cloud or self-hosted). Providers can also offer local utilities for tasks like generating random numbers for unique resource names.
Terraform Custom Provider
According to Terraform documentation,
There are a few possible reasons for authoring a custom Terraform provider, such as:
An internal private cloud whose functionality is either proprietary or would not benefit the open source community.
A "work in progress" provider being tested locally before contributing back.
Extensions of an existing provider
Refer the Hashicorp Documentation on writing custom providers
What is required to develop Custom Provider
- Just small enough Go development knowledge
- Resource creation supported by API calls from the respective provider
Install and Configure Terraform
- Refer here for installing terraform
- Windows
- Download and extract the terraform executable
- Add terraform executable path to ENV PATH variable
- In Linux flavours, Copy the terraform executable in /usr/bin path to execute it from any path.
How to develop provider code with Go
Step 1 Setting up Go develop environment
Refer my Dev community article
Read my article on getting started with Go Hello World
Step 2 Custom Provider Source Code Details
Please check out the provider source files from GitHub Repo Here
- Required source files for custom provider are,
main.go
-
provider.go
-
resource_server.go
The code layout looks like this:
.
├── main.go
├── provider.go
├── resource_server.go
- Go entry point function is
main.go
.
// main.go
package main
import (
"github.com/hashicorp/terraform-plugin-sdk/plugin"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)
func main() {
plugin.Serve(&plugin.ServeOpts{
ProviderFunc: func() terraform.ResourceProvider {
return Provider()
},
})
}
-
provider.go
will have the resource server function calls.
// provider.go
package main
import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func Provider() *schema.Provider {
return &schema.Provider{
ResourcesMap: map[string]*schema.Resource{
"customprovider_server": resourceServer(),
},
}
}
- All the resource creation has to be coded in
resource_server.go
. This file will have the resource function declaration and definition like create, delete etc, it also gets the input params required to create resources.
// resource_server.go
package main
import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func resourceServer() *schema.Resource {
return &schema.Resource{
Create: resourceServerCreate,
Read: resourceServerRead,
Update: resourceServerUpdate,
Delete: resourceServerDelete,
Schema: map[string]*schema.Schema{
"num_sys": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
},
}
}
func resourceServerCreate(d *schema.ResourceData, m interface{}) error {
num_sys := d.Get("num_sys").(string)
d.SetId(num_sys)
/*
API call to be added for respective provider. In case of developing provider for on-prem cloud or public cloud, that is not supported by terraform, add the API call to corresponding Resource creation API
*/
return resourceServerRead(d, m)
}
func resourceServerRead(d *schema.ResourceData, m interface{}) error {
return nil
}
func resourceServerUpdate(d *schema.ResourceData, m interface{}) error {
return resourceServerRead(d, m)
}
func resourceServerDelete(d *schema.ResourceData, m interface{}) error {
return nil
}
- Details regarding the custom provider code in
resource_server.go
:- Our code repo example implemented with mock resource creation for the provider called 'customprovider'.
- In real-time case, it has to be changed for the provider name of respective cloud or on-premises server.
- Most of providers have API calls to be consumed for resource operation like create/update/delete etc.. So We need to define the logic of resource operations like create and delete using the custom provider api calls, to apply the terraform template.
- Please add the API call implementation in the
/* commented out */
section inresource_server.go
Step 3 Build go code and create tf provider executable
cd tf_custom_provider/
go mod init
go mod tidy
go build -o terraform-provider-customprovider
Please note,
Third-party plugins (both providers and provisioners) can be manually installed into the user plugins directory
Located at %APPDATA%\terraform.d\plugins on Windows and ~/.terraform.d/plugins on other systems.
Copy the custom provider executable created in the step above to Terraform plugin directory
- After adding the logic for resource operations in
resource_server.go
, our custom provider is ready to get tested
Step 4 Create terraform file
Test the provider by creating main.tf
, by providing the resource inputs. In our sample just the number of server count added as an input parameter for demo purpose.
Create or Edit main.tf
file with code to create custom provider resource
resource "customprovider_server" "my-server-name" {
num_sys = "2"
}
Step 5 Testing Provider Create and Destroy resource
- The custom provider executable should be placed inside the "~/.terraform.d/plugins" (in Linux server) path to enable the access to the custom provider functionality
- Execute the following Terraform commands to verify the custom provider functionalities we have added,
terraform init
terraform plan
terraform apply
terraform destroy
Bibliography and Reference
Terraform Docs
Custom Provider Lab Tutorial
Custom Provider Easy Tutorial
Top comments (0)