写一个简单的terraform provider
背景
在云计算不断发展的今天, 基础设施即代码(Infrastructure as Code)逐渐成为趋势. 它将基础设施代码化,直接继承了代码管理的所有优点,比如: 版本管理, 跟CICD集成, 确保测试生产环境的一致性等等. 能极大的提高效率和减少人为错误. 而HashiCorp的Terraform无疑是这个领域的领头羊. 至于Terraform是什么,我就不多介绍了. 本文假设你已经有了一定Terraform基础, 将介绍如何写一个简单的Terraform Provider.
准备
Terraform其实由Terraform Core和Terraform Plugins (各种Provider)组成:
- Terraform Core: 负责读取配置文件并构建资源关系图谱
- Terraform Provider: Provider通过基本 CRUD API 与第三方服务进行通信
比如创建阿里云的一台ECS就可以通过以下的配置文件实现:
1 | provider "alicloud" { |
其背后就是调用了阿里云的OpenAPI实现的, 下面我用一个简单的例子来模拟一下这个过程.
第一步: 定义User对象,并构建出对应的API
我们先定义一个简单的类User
1 | public class User { |
接着构建出对应的CRUD API
Create
1 | curl --request POST 'http://localhost:8080/rest/user' \ |
Read
1 | curl --request GET 'http://localhost:8080/rest/user/4126ef31-4f4e-453d-9290-6360b77c5a6c' |
Update
1 | curl --request PUT 'http://localhost:8080/rest/user/4126ef31-4f4e-453d-9290-6360b77c5a6c' \ |
Delete
1 | curl --request DELETE 'http://localhost:8080/rest/user/4126ef31-4f4e-453d-9290-6360b77c5a6c' |
List
这个接口用于测试的时候方便校验后台数据,Provider不使用
1 | curl --request GET 'http://localhost:8080/rest/users' |
以上就是一个User类的定义,以及使用curl操作API的代码,是不是非常简单,对应的服务端的代码我不就展示了,(代码在这里)可以用自己喜欢的技术栈实现一个就可以了,下面我们开始来构建对应的Terraform Provider
第二步: 构建Terraform provider
在开始构建之前,我们先定义好一些meta信息如下 (这个关系到provider文件的存放地址):
1 | provider path: ~/.terraform.d/plugins/${host_name}/${namespace}/${type}/${version}/${target} |
创建如下目录结构和文件, 我们会定义一个resource(User)和一个data(Country), 这两种是我们最常用的类型
1 | demo_provider |
在demo_provider目录下执行编译 (对应的源代码附在最后面)
1 | go mod init |
别忘记需要安装Terraform, 要不然后面测试会跑不起来
第三部: 测试
1 | terraformtest |
main.tf
1 | # resource test |
versions.tf
1 | terraform { |
运行测试
1 | # 在terraformtest目录下执行 |
到此,一个简单的Terraform Provider已经构建完成了,我们可以继续修改main.tf来测试修改和删除的case. 真实的Provider的构建会比这个复杂很多,也会有更多的特殊情况需要处理,这里只是用最简单的例子而已.
附录: Provider源代码
main.go
1 | package main |
provider.go
1 | package main |
data_country.go
1 | package main |
resource_user.go
1 | package main |