Terraform チュートリアル「Custom Framework Providers」を試した❗️
Terraform から RESTful API を操作するカスタムプロバイダを実装しながら Terraform Plugin Framework の仕組みを学べて非常に良かった👌チュートリアルは計11種類から構成されていて一歩一歩進められる.3時間ぐらいあれば十分終わると思うけど,僕自身は朝活として毎日1,2個をコツコツと進めていた🕐
- Implement a provider with the Terraform Plugin Framework
- Configure provider client
- Implement data source
- Implement logging
- Implement resource create and read
- Implement resource update
- Implement resource delete
- Implement resource import
- Implement automated testing
- Implement documentation generation
- Release and publish to the Terraform registry
現在 Terraform でカスタムプロバイダを実装するためには Terraform Plugin Framework を使う選択肢と Terraform Plugin SDKv2 を使う選択肢がある.ドキュメントには今後新しく実装する場合は Terraform Plugin Framework 推奨と書いてある📝
Hashicups API ☕
チュートリアルでは Hashicups という架空のコーヒーショップアプリケーションの RESTful API を Terraform から操作できるようにする☕ API リソースとしてはコーヒーを表現する /coffees
と注文を表現する /orders
があって,他にも JWT を使った認証の仕組みもある💡実装や Docker Compose ファイルは GitHub の hashicorp-demoapp/product-api-go
リポジトリにある.
試しに Hashicups API を Docker Compose で起動して,API 操作を簡単に紹介する❗️
POST /signup
$ curl -X POST -s localhost:19090/signup -d '{"username":"education", "password":"test123"}'
POST /signin
$ HASHICUPS_TOKEN=$(curl -X POST -s localhost:19090/signin -d '{"username":"education", "password":"test123"}' | jq -r .token)
GET /coffees
$ curl -s http://localhost:19090/coffees | jq . [ { "id": 1, "name": "HCP Aeropress", "teaser": "Automation in a cup", "collection": "Foundations", "origin": "Summer 2020", "color": "#444", "description": "", "price": 200, "image": "/hashicorp.png", "ingredients": [ { "ingredient_id": 6 } ] }, { "id": 2, "name": "Packer Spiced Latte", "teaser": "Packed with goodness to spice up your images", "collection": "Origins", "origin": "Summer 2013", "color": "#1FA7EE", "description": "", "price": 350, "image": "/packer.png", "ingredients": [ { "ingredient_id": 1 }, { "ingredient_id": 2 }, { "ingredient_id": 4 } ] }, (中略) { "id": 9, "name": "Waypointiato", "teaser": "Deploy with a little foam", "collection": "Discoveries", "origin": "Fall 2020", "color": "#14C6CB", "description": "", "price": 250, "image": "/waypoint.png", "ingredients": [ { "ingredient_id": 1 }, { "ingredient_id": 2 } ] } ]
GET /orders
$ curl -s -H "Authorization: ${HASHICUPS_TOKEN}" http://localhost:19090/orders []
Terraform コード main.tf
まずは実装したカスタムプロバイダを使った Terraform コード main.tf
を紹介するのが早いと思う.hashicups_order
リソースを使って注文できる❗️
terraform { required_providers { hashicups = { source = "hashicorp.com/edu/hashicups" } } required_version = ">= 1.1.0" } provider "hashicups" { username = "education" password = "test123" host = "http://localhost:19090" } resource "hashicups_order" "edu" { items = [ { coffee = { id = 3 } quantity = 2 }, { coffee = { id = 1 } quantity = 2 } ] } output "edu_order" { value = hashicups_order.edu }
また hashicups_coffees
データソースの実装もできる❗️
data "hashicups_coffees" "edu" {} output "edu_coffees" { value = data.hashicups_coffees.edu }
実際に terraform apply
コマンドを実行してみると注文を登録できる☕
$ terraform apply (中略) Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes hashicups_order.edu: Creating... hashicups_order.edu: Creation complete after 0s [id=1] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: edu_order = { "id" = "1" "items" = tolist([ { "coffee" = { "description" = "" "id" = 3 "image" = "/vault.png" "name" = "Vaulatte" "price" = 200 "teaser" = "Nothing gives you a safe and secure feeling like a Vaulatte" } "quantity" = 2 }, { "coffee" = { "description" = "" "id" = 1 "image" = "/hashicorp.png" "name" = "HCP Aeropress" "price" = 200 "teaser" = "Automation in a cup" } "quantity" = 2 }, ]) "last_updated" = "Sunday, 29-Oct-23 20:53:38 JST" }
Hashicups API から直接注文を取得すると期待通りに登録されている👏
$ curl -s -H "Authorization: ${HASHICUPS_TOKEN}" http://localhost:19090/orders | jq . [ { "id": 1, "items": [ { "coffee": { "id": 3, "name": "Vaulatte", "teaser": "Nothing gives you a safe and secure feeling like a Vaulatte", "collection": "Foundations", "origin": "Spring 2015", "color": "#FFD814", "description": "", "price": 200, "image": "/vault.png", "ingredients": [ { "ingredient_id": 1 }, { "ingredient_id": 2 } ] }, "quantity": 2 }, { "coffee": { "id": 1, "name": "HCP Aeropress", "teaser": "Automation in a cup", "collection": "Foundations", "origin": "Summer 2020", "color": "#444", "description": "", "price": 200, "image": "/hashicorp.png", "ingredients": [ { "ingredient_id": 6 } ] }, "quantity": 2 } ] } ]
他にも terraform import
コマンドを実行できるようにしたり,terraform-plugin-testing を使ってテストコードを実装したり,実際にカスタムプロバイダを実装するときに使うことになるであろうトピックに触れられたところも良かった👏
$ terraform import hashicups_order.edu 2 hashicups_order.edu: Importing from ID "2"... hashicups_order.edu: Import prepared! Prepared hashicups_order for import hashicups_order.edu: Refreshing state... [id=2] Import successful! $ TF_ACC=1 go test -count=1 -v === RUN TestAccCoffeesDataSource --- PASS: TestAccCoffeesDataSource (1.38s) PASS ok terraform-provider-hashicups/internal/provider 1.599s $ TF_ACC=1 go test -count=1 -run='TestAccOrderResource' -v === RUN TestAccOrderResource --- PASS: TestAccOrderResource (2.88s) PASS ok terraform-provider-hashicups/internal/provider 3.226s
Terraform Plugin Framework
Terraform Plugin Framework では Metadata
にリソース名・データソース名を定義して,Schema
にリソースの構造体を定義する.さらに Create
/ Read
/ Update
/ Delete
にリソースの操作を実装する.Terraform コード main.tf
側のコードと見比べることで「なるほど💡こうやってカスタムプロバイダと Hashicups API が連携してるのか❗️」というイメージを深めることができて,とてもわかりやすい仕組みになっていると思った.
そして Create
/ Read
/ Update
/ Delete
では Hashicups API を直接呼び出すのではなく hashicups-client-go を使って r.client.CreateOrder()
や r.client.GetOrder()
のように実行する.
まとめ
Terraform Plugin Framework を使ったカスタムプロバイダの実装に入門できる Terraform チュートリアル「Custom Framework Providers」を試した❗️Hashicups という架空のコーヒーショップアプリケーションの RESTful API を Terraform から操作できるようにしながら Terraform Plugin Framework の仕組みを学べて非常に良かった👌
Terraform Registry に公開されてる Terraform Provider Hashicups はこちら〜 \( 'ω')/