Terraform 开发指南
摘要:?本文主要向大家展示如何為阿里云 Terraform Provider 貢獻(xiàn)自己的力量,幫助開發(fā)者和志同道合的朋友盡快加入到開源生態(tài)的建設(shè)中來(lái)。 本文面向所有的對(duì)Terraform熟悉和感興趣的朋友,如果您還不了解Terraform,快快戳這里。
本文主要向大家展示如何為阿里云 Terraform Provider?貢獻(xiàn)自己的力量,幫助開發(fā)者和志同道合的朋友盡快加入到開源生態(tài)的建設(shè)中來(lái)。
本文面向所有的對(duì)Terraform熟悉和感興趣的朋友,如果您還不了解Terraform,快快戳這里。
本文會(huì)從環(huán)境搭建和開發(fā)規(guī)范兩個(gè)方面向大家展示如何開放 terraform provider。
環(huán)境搭建
安裝 Golang
本地安裝go >1.10.0 詳見(jiàn):https://golang.org/dl/
安裝 Terraform
本地安裝 Terraform > 0.11, 詳見(jiàn):?https://www.terraform.io/intro/getting-started/install.html
安裝 Terraform Provider
fork 并下載 repo:?https://github.com/alibaba/terraform-provider
cd $GOPATH mkdir -p src/github.com/alibaba cd $GOPATH/src/github.com/alibaba git clone git clone git@github.com:<your-git-id>/terraform-provider.git利用 glide 安裝依賴(how to install glide)
# switch to project cd $GOPATH/src/github.com/alibaba/terraform-provider# get all dependencies and install modules glide up設(shè)置環(huán)境變量,省去每次測(cè)試時(shí)輸入AK的要求
# set the creds export ALICLOUD_ACCESS_KEY="***" export ALICLOUD_SECRET_KEY="***"Resource 開發(fā)
Resource 開發(fā)是根據(jù)阿里云的OpenAPI在terraform provider中實(shí)現(xiàn)對(duì)阿里云產(chǎn)品和資源的插件。
規(guī)劃和設(shè)計(jì)
每個(gè)Resource的實(shí)現(xiàn)不是根據(jù)阿里云幫助文檔對(duì)OpenAPI的簡(jiǎn)單調(diào)用,要對(duì)產(chǎn)品的設(shè)計(jì),功能以及使用有較深的理解,通常遵循如下設(shè)計(jì)原則:
每個(gè)resource只管理自身的功能,與其他resource引用或者關(guān)聯(lián)交由關(guān)系性資源來(lái)完成,如ECS instance只管理實(shí)例自身的功能,對(duì)于掛哪個(gè)數(shù)據(jù)盤,分配哪個(gè)EIP交由attachment資源來(lái)完成
對(duì)于資源與資源之間的關(guān)系,需要單獨(dú)定義一個(gè)邏輯resource,來(lái)完成資源與資源之間的關(guān)聯(lián),如磁盤掛載,eip的掛載,ess與ecs的關(guān)聯(lián)等
參數(shù)要盡可能簡(jiǎn)潔,不要有冗余的參數(shù),以RDS instance為例,對(duì)于參數(shù)zoneId,VpcId以及VSwitchId而言,只需要定義zoneId和VpcId就是冗余參數(shù),因?yàn)樵谡{(diào)用具體API之前,可以通過(guò)vswitchId來(lái)獲取這兩個(gè)參數(shù),但某些特殊的場(chǎng)景除外,比如RDS支持Multiple zone,所以zonId也需要保留。如果可以設(shè)置Default,最好顯示設(shè)置。
每個(gè)參數(shù)字段要具有清晰的語(yǔ)義,幫助用戶更好的理解。對(duì)于一些公共的,統(tǒng)一的參數(shù),如可用區(qū),slb ID,最好跟其他資源保持一致:availability_zone,?load_balancer_id.
參數(shù)校驗(yàn)
有些參數(shù)需要做一些簡(jiǎn)單的校驗(yàn),提前提醒客戶使用正確的可選值。除此之外,對(duì)于某些參數(shù),要做diff判斷,以自動(dòng)屏蔽某些不起作用的參數(shù),如:對(duì)于ECS而言,選擇PostPaid,意味著所有與PrePaid相關(guān)的參數(shù)?period,period_unit,renewal_status,auto_renew_period都將失效,具體表現(xiàn)為在執(zhí)行terraform plan的時(shí)候,這些參數(shù)不會(huì)做diff比較。
基本實(shí)現(xiàn)
每個(gè)Resource需要實(shí)現(xiàn)Create,Read,Update,Delete,Import五個(gè)功能:
-
Create
- 調(diào)用產(chǎn)品創(chuàng)建API,實(shí)現(xiàn)對(duì)某個(gè)資源的創(chuàng)建,并將resource id 寫入到state文件中
- 如果資源沒(méi)有ID,比如安全組規(guī)則,那么resource要自己按照一定的規(guī)則自行實(shí)現(xiàn)一個(gè)ID,對(duì)terraform而言,該ID是resource的唯一標(biāo)識(shí),后續(xù)對(duì)resource的所有操作都需要依賴于該ID進(jìn)行
- Create 的實(shí)現(xiàn)邏輯要盡可能簡(jiǎn)單,以成功創(chuàng)建資源為目標(biāo),太多的復(fù)雜邏輯會(huì)降低資源創(chuàng)建的成功率
- 復(fù)雜的功能實(shí)現(xiàn)可交由 Update 來(lái)完成
- Create之后通常調(diào)用Update方法來(lái)完成更多功能的實(shí)現(xiàn)
-
Update
- 調(diào)用產(chǎn)品的Update或Modify API,實(shí)現(xiàn)對(duì)resource更多功能的支持以及對(duì)已有屬性的修改
- Update之前要打開Partial?d.Partial(true),并在每步修改后進(jìn)行時(shí)時(shí)更新,如d.SetPartial("bandwidth"),以保證后面的每一步成功的更改都能被及時(shí)的寫入到state 文件中。
- Update 之后,調(diào)用 Read 方法,實(shí)現(xiàn)對(duì)resource 所有屬性的展示。
-
Read
- 調(diào)用 Describe 或者 List API,實(shí)現(xiàn)對(duì)已有資源的查詢和寫入state
- 如果找不到指定的資源,要將resource ID標(biāo)記為“”,以告訴terraform,當(dāng)前這個(gè)資源已經(jīng)不存在了。
-
Delete
- 調(diào)用Delete API實(shí)現(xiàn)對(duì)指定資源的刪除和釋放
- 為了保證resource成功釋放,需要加入retry策略來(lái)避免因資源依賴或者異步操作而引起的刪除失敗問(wèn)題
- 通常,resource釋放后要再次調(diào)用查詢API來(lái)完成刪除操作的驗(yàn)證
-
Import
- 調(diào)用查詢API實(shí)現(xiàn)對(duì)已有資源的導(dǎo)入
- 通常只需要方法申明,無(wú)需多余的實(shí)現(xiàn)邏輯,它會(huì)借助Read方法來(lái)完成對(duì)資源的查詢和導(dǎo)入
基本工作原理
執(zhí)行terraform 命令,完成對(duì)資源的管理,主要命令包含以下幾個(gè):
實(shí)現(xiàn)對(duì)資源的預(yù)覽。該命令會(huì)調(diào)用對(duì)應(yīng)資源的Read?方法來(lái)獲取模板中定義的資源。如果資源尚未創(chuàng)建,及當(dāng)前目錄下的state文件為空,直接展示即將創(chuàng)建的資源,否則展示要變更的資源
terrform apply
實(shí)現(xiàn)對(duì)資源的創(chuàng)建和更新。新資源調(diào)用Create,已有資源調(diào)用Update完成對(duì)資源的修改。
terraform destroy
調(diào)用Destroy完成對(duì)資源的銷毀。
調(diào)用Read方法完成對(duì)已有資源的導(dǎo)入,將已有資源加入到terraform的管理序列中來(lái)。但要注意,由于已有資源不一定是通過(guò)terraform創(chuàng)建的,所有導(dǎo)入成功后,記得運(yùn)行terraform plan進(jìn)行對(duì)比,手動(dòng)補(bǔ)齊模板。
注意事項(xiàng)
Data Source 開發(fā)
Data Source 開發(fā)是調(diào)用阿里云資源的查詢API完成對(duì)特定資源的查詢和展示。
規(guī)劃和設(shè)計(jì)
每個(gè)Data Source的實(shí)現(xiàn)要根據(jù)API的字段和資源屬性,為用戶提供更好的查詢體驗(yàn),最好可以支持模糊查詢。參數(shù)設(shè)計(jì)原則除了與Resource設(shè)計(jì)原則類似外,還應(yīng)該提供一個(gè)參數(shù)output_file來(lái)將查詢到的結(jié)果輸出到文件中,供用戶參考。
基本實(shí)現(xiàn)
每個(gè)Data Source只需實(shí)現(xiàn)Read方法,該方法用來(lái)查詢并過(guò)濾符合條件的所有的resource,然后將過(guò)濾的結(jié)果以列表的方式展示出來(lái)。在具體實(shí)現(xiàn)過(guò)程中,需要注意以下幾點(diǎn):
測(cè)試
在完成模塊開發(fā)后,要對(duì)每個(gè)resource和data source的功能進(jìn)行測(cè)試,測(cè)試的方法是編寫對(duì)應(yīng)的測(cè)試用例。
測(cè)試用例的編寫要遵循以下幾個(gè)原則:
如何運(yùn)行測(cè)試用例?
以ECS instance 舉例,運(yùn)行如下的測(cè)試命令,可以實(shí)現(xiàn)對(duì)目錄alicloud下所有以TestAccAlicloudInstance為前綴的測(cè)試用例的運(yùn)行:
其中,timeout?表示這個(gè)測(cè)試用例運(yùn)行的超時(shí)時(shí)長(zhǎng)。
如果想要精確到具體的測(cè)試用例,補(bǔ)全測(cè)試用例的名稱即可。
文檔
文檔是用戶使用provider的基礎(chǔ),文檔的編寫非常重要,需遵循如下幾個(gè)原則:
樣例
為了更好的幫助用戶使用新增的resource,在完成以上工作后,需要為當(dāng)前的這個(gè)resource或者當(dāng)前這類resource增加一個(gè)example,來(lái)指導(dǎo)用戶編寫對(duì)應(yīng)的模板。該樣例是一個(gè)真實(shí)的可運(yùn)行的模板,通常包含以下四部分:
代碼提交
完成了以上功能的實(shí)現(xiàn)和代碼的編寫后,接下來(lái)最關(guān)鍵的就是代碼的提交,我們的代碼最好優(yōu)先提交到dev分支,具體的步驟分為以下幾步:
Commit
為了避免出現(xiàn)代碼的錯(cuò)亂,降低review的復(fù)雜度,Commit要細(xì)化,每一功能點(diǎn)或者一次的修改(不論改動(dòng)有多小)對(duì)應(yīng)一個(gè)Commit。為了防止功能和代碼的相互沖突,每個(gè)功能點(diǎn)對(duì)應(yīng)一個(gè)branch。
Rebase
提交代碼前一定要Rebase,具體操作步驟如下:
Rebase之前,首先需要配置你的Remote,假定你origin?指向了你的fork:
接著,將主倉(cāng)庫(kù)配置為你的remote,如起名為“alicloud”
$ git remote add alicloud https://github.com/alibaba/terraform-provider.git$ git remote -vorigin git@github.com:YOUR_GITHUB_USERNAME/terraform-provider.git (fetch)origin git@github.com:YOUR_GITHUB_USERNAME/terraform-provider.git (push)alicloud https://github.com/alibaba/terraform-provider.git (fetch)alicloud https://github.com/alibaba/terraform-provider.git (push)檢查當(dāng)前倉(cāng)庫(kù)的狀態(tài)
$ git statusOn branch YOUR_BRANCHYour branch is up-to-date with 'origin/YOUR_BRANCH'.nothing to commit, working tree clean完成commit和remote配置后,即可進(jìn)行rebase操作:
如果有沖突,解決沖突后繼續(xù) rebase,直到所有沖突都解決,之后再次檢查狀態(tài):
$ git statusOn branch YOUR_BRANCHYour branch and 'origin/YOUR_BRANCH' have diverged,and have 4 and 1 different commits each, respectively.(use "git pull" to merge the remote branch into yours)nothing to commit, working tree clean完成rebase操作后,上傳代碼:
如遇到提交失敗,可使用-f?或者--force?來(lái)強(qiáng)制提交
Submitting Your Pull Request
完成代碼上傳后,在Github控制臺(tái)將你的代碼提交到主倉(cāng)庫(kù)的dev分支,并對(duì)PR做一個(gè)簡(jiǎn)單的描述和介紹。
如果代碼有問(wèn)題,在Review結(jié)束后,需要對(duì)已提交的代碼做修改,首先將上次提交進(jìn)行回退:
之后,stash并利用rebase下載最新的代碼,以避免不必要的沖突:
$ git stashSaved working directory and index state WIP on YOUR_BRANH: xxxxxHEAD is now at xxxxx# rebase 下載最新代碼$ git pull --rebase alicloud devrebase順利執(zhí)行之后,恢復(fù)stash代碼:
$ git stash popOn branch YOUR_BRANCHChanges not staged for commit:xxxxx根據(jù)review意見(jiàn),繼續(xù)修改代碼,之后再次進(jìn)行代碼commit,rebase和push即可。
寫在最后
本文主要講述了如何為阿里云的Terraform-Provider貢獻(xiàn)代碼的一些流程和注意事項(xiàng),歡迎大家積極加入到Terraform Provider的建設(shè)中來(lái),謝謝大家。
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載
總結(jié)
以上是生活随笔為你收集整理的Terraform 开发指南的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 阿里敏捷教练何勉:论精益思想及精益产品开
- 下一篇: Apache RocketMQ 正式开源