A presentation at CfgMgmtCamp in in Ghent, Belgium by Horacio Gonzalez
Let’s dive into Terraform provider creation Aurélie Vache - Horacio Gonzalez 2023-02-06
Aurélie Vache @aurelievache DevRel at Conferences organizer Tech visual articles & books Sketchnoter … & ❤ Retrogaming https://www.youtube.com/c/AurelieVache https://dev.to/aurelievache/ Les Productions de MOA
Horacio Gonzalez @LostInBrittany Spaniard lost in Brittany, developer, dreamer and all-around geek
OVHcloud: A global leader Web Cloud & Telcom 30 Data Centers in 12 locations 1 Million+ Servers produced since 1999 Private Cloud 34 Points of Presence on a 20 TBPS Bandwidth Network 1.5 Million Customers across 132 countries Public Cloud 2200 Employees worldwide 3.8 Million Websites hosting Storage 115K Private Cloud VMS running 1.5 Billion Euros Invested since 2016 300K Public Cloud instances running P.U.E. 1.09 Energy efficiency indicator 380K Physical Servers running in our data centers 20+ Years in Business Disrupting since 1999 Network & Security
Warning Gophers, gophers everywhere!
Credit where it is due All the gophers you will see are drawn by Aurélie and Horacio, and are based on the Go mascot designed by Renee French which is licensed under CC BY 3.0.
Terraform De facto standard for IaC
Infrastructure as Code (IaC)
Terraform becoming the de facto standard
HashiCorp Terraform
Modular architecture: providers
Configuration packages: modules
Terraform registry
Writing Terraform providers Defining new Terraform resources
Provider SDK https://developer.hashicorp.com/terraform/plugin/sdkv2
Installing Terraform providers $ terraform init Initializing provider plugins… - Finding terraform.local/local/myprovider versions matching “0.0.1”… - Installing terraform.local/local/myprovider v0.0.1…
Installing providers from registry $ vi provider.tf terraform { required_providers { thenamespace = { source = “thenamespace/myprovider” } } } If your provider is on the official registry at https://registry.terraform.io/providers/thenamespace/myprovider
Installing providers locally $ go build -o terraform-provider-myprovider $ mkdir -p ~/.terraform.d/plugins/terraform.local/local/myprovider/0.0.1/darwin_amd64 $ mv terraform-provider-myprovider ~/.terraform.d/plugins/terraform.local/local/myprovider/0.0.1/darwin_amd64
Installing providers locally $ vi provider.tf terraform { required_providers { thenamespace = { source = “terraform.local/local/myprovider” version = “0.0.1” } } }
Do I need a Terraform provider? If you have an API, you should have a Terraform provider
Letʼs create a provider! Step by step
What do we want? ● In a simple and easy Terraform provider ● Handle cute Gophers ● In Go, because providers are made in Go 😁
Everything begins with an API https://github.com/scraly/gophers-api
For the demos we will use Gitpod Automated, ephemeral developer environments in the web
Everything begins with an API $ task swagger.serve task: [swagger.serve] swagger serve -F swagger ./pkg/swagger/swagger.yml —no-open 2022/10/31 20:16:51 serving docs at http://localhost:38457/docs
Everything begins with an API
Everything begins with an API $ task run task: [run] GOFLAGS=-mod=mod go run internal/main.go 2022/10/30 20:22:05 Serving gophers API at http://[::]:8080 $ curl localhost:8080/gophers [{“name”:”5th-element”,”displayname”:”5th Element.png”,”url”:”https://raw.githubusercontent.com/scraly/gophers/main/5th-ele ment.png”}]
Gophers deserve to be seen https://github.com/LostInBrittany/gophers-api-watcher
Everything begins with an API $ curl -X POST localhost:8080/gopher -H “Content-Type: application/json” -d \ ‘{“name”:”yoda-gopher”,”displayname”:”Yodada Gopher”,”url”:”https://raw.githubusercontent.com/scraly/gophers/main/yoda-gopher. png”}’ $ curl -X DELETE localhost:8080/gopher?name=5th-element $ curl -X PUT localhost:8080/gopher \ -H “Content-Type: application/json” -d \ ‘{“name”:”yoda-gopher”,”displayname”:”Yoda Gopher”,”url”:”https://raw.githubusercontent.com/scraly/gophers/main/yoda-gopher. png”}’
Let’s create our provider! 1. Create the skeleton of our provider thanks to scaffolding https://github.com/hashicorp/terraform-provider-scaffolding
Let’s create our provider! https://github.com/scraly/terraform-provider-gophers
Demo time!
Provider > Makefile
Demo time!
Some concepts to introduce…
Customizing provider definition
Test it! the provider $ vi provider.tf terraform { required_providers { gophers = { source = “terraform.local/local/gophers” version = “0.0.1” } } } provider “gophers” { endpoint = “http://myawesomeurl.com” }
Adding the schema “Translating” the Swagger into a Go schema
Adding datasource: gophers
Test it! $ vi gophers_data.tf # List of available gophers data “gophers” “my_gophers” { } output “return_gophers” { value = length(data.gophers.my_gophers.gophers) >= 1 }
Adding datasource: gopher
Test it! $ vi gopher_data.tf # Display information about a Gopher data “gophers_gopher” “moultipass” { name = “5th-element” }
Adding resource: gopher
Test it! $ vi gopher_resource.tf resource “gophers_gopher” “x-files” { name = “x-files” displayname = “X Files” url } = “https://raw.githubusercontent.com/scraly/gophers/main/x-files.png”
Testing the provider locally $ go build -o terraform-provider-gophers $ mkdir -p ~/.terraform.d/plugins/terraform.local/local/gophers/0.0.1/darwin_arm64 $ mv terraform-provider-gophers ~/.terraform.d/plugins/terraform.local/local/gophers/0.0.1/darwin_arm64 $ make install
Testing the provider locally $ rm .terraform.lock.hcl && terraform init $ terraform apply
Testing the provider locally $ terraform destroy
OVHcloud Terraform Provider To easily manage OVHcloud products
OVHcloud Terraform Provider https://registry.terraform.io/providers/ovh/ovh/latest/docs
OVHcloud Terraform Provider https://github.com/ovh/terraform-provider-ovh
Best practices But we have learnt with our providers
Doc is not optional $ tfplugindocs generate Generate the doc of your provider. Based on the schema the provider exposes. https://github.com/hashicorp/terraform-plugin-docs
Write useful examples in your doc Examples in your documentation should be: ● Useful ● Up-to-date ● Working Users will copy paste your examples! 😉
And… test your doc! Use the doc preview tool https://registry.terraform.io/tools/doc-preview
Acceptance tests $ make testacc $ make testacc TESTARGS=”-run TestAccDataSourceGopher”
Provider is a reflection of your API client Think about API first design
Use the logs for debugging $ TF_LOG=INFO terraform plan
Set timeouts / retry Timeouts: &schema.ResourceTimeout{ Create: schema. DefaultTimeout (20 * time.Minute), Update: schema. DefaultTimeout (20 * time.Minute), Delete: schema. DefaultTimeout (20 * time.Minute), }, Timeout/retry par resource
Read the code See how other open source providers are written
The “3 P” rule Practice, practice, practice
One more thing… Or two or three
A handy cheat sheet https://github.com/scraly/terraform-cheat-sheet/
Thank you! https://bit.ly/tf-provider-cfgmgtcamp
We ❤ feedbacks https://bit.ly/vote-tf-provider-cfgmgtcamp
Currently when we think of Infrastructure as Code (IaC), one tool seems to stand out and has become a de-facto standard: Terraform.
With Terraform you can easily build, edit and version your whole infrastructure by using Terraform builtin providers or custom ones.
But sometimes there is no provider for the infrastructure you intend to use, not even the lone no-star repository in a lost corner of the internet, only a custom REST API. What can you do? Going back to manual operations? Create your own scripts?
In this talk Horacio and Aurélie will show you, step by step, how to go from an infrastructure API to a fully functional yet light Terraform provider. By taking as base a REST API, they will explain the basics of provider creation, give some pointers on how to do a simple yet efficient provider architecture and show you the code and the provider in action.
Will they succeed in this new mission?