本文主要向大家展示如何为阿里云 Terraform Provider 贡献自己的力量,帮助开发者和志同道合的朋友尽快加入到开源生态的建设中来。
本文面向所有的对Terraform熟悉和感兴趣的朋友,如果您还不了解Terraform,快快戳这里。
本文会从环境搭建和开发规范两个方面向大家展示如何开放 terraform provider。
环境搭建
安装 Golang
本地安装go >1.10.0 详见:https://golang.org/dl/
安装 Terraform
本地安装 Terraform > 0.11, 详见: https://www.terraform.io/intro/getting-started/install.html
安装 Terraform Provider
-
fork或者直接 Clone repo https://github.com/terraform-providers/terraform-provider-alicloud 到:$GOPATH/src/github.com/terraform-providers/terraform-provider-alicloud
mkdir -p $GOPATH/src/github.com/terraform-providers cd $GOPATH/src/github.com/terraform-providers git clone git@github.com:terraform-providers/terraform-provider-alicloud
-
编译并 build Provider:
cd $GOPATH/src/github.com/terraform-providers/terraform-provider-alicloud # make build 会同时build出mac,Linux和windows的provider,并将生成的provider存放在当前目录的`bin`目录下 make build # 如果你只想build单一系统的provider,只需要在执行的时候指定操作系统名称即可 make mac / make linux / make windows # 如果你想开发或者测试,以下命令会将build好的provider安装到 Terrafrom 所在的安装目录,无需自行安装 Mac: make dev Linux: make devlinux Windows: make devwin
-
设置环境变量,省去每次测试时输入AK的要求
# set the creds export ALICLOUD_ACCESS_KEY="***" export ALICLOUD_SECRET_KEY="***"
Resource 开发
Resource 开发是根据阿里云的OpenAPI在terraform provider中实现对阿里云产品和资源的插件。在terraform中,一个阿里云的云资源,如一台ECS instance,一块磁盘,一个VPC,一个SLB实例等,都可以对应一个resource,除此之外,资源与资源之间的关联关系,如磁盘的挂载,EIP的绑定,ECS 实例添加到SLB中等,也可以定义为一个单独的资源,这样带来的好处是,这些关联关系可以在编排模板中被大量的复用,模板结构清晰的同时,降低用户编写模板的复杂度。
规划和设计
每个Resource的实现不仅仅是根据阿里云帮助文档对OpenAPI的简单调用,还要对产品的设计,功能以及使用有较深的理解,通常遵循如下设计原则:
-
自管理
每个resource只管理自身的功能,与其他resource引用或者关联交由关系性资源来完成,如ECS instance只管理实例自身的功能,对于挂哪个数据盘,分配哪个EIP交由attachment资源来完成
-
松耦合
对于资源与资源之间的关联关系,需要单独定义一个逻辑resource,来完成资源与资源之间的关联,如磁盘挂载,eip的挂载,ess与ecs的关联等。
-
参数简洁
参数要尽可能简洁,不要有冗余的参数,以RDS instance为例,对于参数zoneId,VpcId以及VSwitchId而言,只需要定义zoneId和VpcId就是冗余参数,因为在调用具体API之前,可以通过vswitchId来获取这两个参数,但某些特殊的场景除外,比如RDS支持Multiple zone,所以zonId也需要保留。 如果可以设置Default,最后显示设置。
-
语义清晰
每个参数字段要具有清晰的语义,帮助用户更好的理解。对于一些公共的,统一的参数,如可用区,slb ID,最好跟其他资源保持一致:`availability_zone`, `load_balancer_id`。 再如,在好多资源中都有包年包月和按量付费之分,计费类型可统一定义为“instance_charge_type”。对于一些语义清楚的参数,如资源名称VpcName,VSwitchName,LoadBalancerName等,在具体的资源中只需用同一字段"name"来定义就好了。
-
参数校验
有些参数需要做一些简单的校验,提前提醒客户使用正确的可选值。除此之外,对于某些参数,要做diff判断ÿ