Module 是一個Terraform 模闆,是對多個子節點,子資源,子架構模闆的組合和抽象。利用Module 在降低模闆編寫和維護複雜度的同時,使得模闆結構更加簡潔清楚。為什麼要使用 Module,詳見文章 Module 讓 Terraform 使用更簡單
。
本文将根據自己對 Module 的了解,向大家講解如何編寫一個通用,标準的 Module。
建立 Module 的 Github 倉庫
在 Terraform 官方注冊 module,目前隻支援 Github 的倉庫,是以,在編寫模闆之前,必須先建立一個
标準的 Github 倉庫:
- 倉庫必須是 Public 的;
- 倉庫名稱必須符合格式:
,如terraform-<PROVIDER>-<NAME>
,terraform-alicloud-ecs-instance
等terraform-alicloud-vpc
- 倉庫建好後必須給倉庫添加一個描述
為了更好的管理所有阿裡雲的terraform module,現在所有的倉庫都建在組織
terraform-alicloud-modules
下。當有建立倉庫需求時,可聯系負責人。
編寫Module
Module 倉庫建立完畢後,首先要 fork 倉庫并将其clone到本地。接下來,開始 Mudole 的編寫工作。官方已經給出了一個标準的 Module 應該遵循的原則和規範,詳見
standard-module-structure. 本文将在此基礎上進行補充。
- 基本原則
- 每個Module不宜包含過多的資源,要盡可能隻包含同一産品的相關資源,這樣帶來的好處是Module的複雜度不高,便于維護和閱讀;
- 對于統一産品的不同資源,應該分别放在不同的子module中,然後在最外層的main.tf中組織所有的子資源,比如 module slb 中定義了兩個資源
和slb instance
,這兩個子資源分别定義在了slb attachment
modules/slb
中,然後在最外層的modules/slb_attachment
中将這兩個module組合為一個新的modulemain.tf
- 每個module要盡可能單元化,以便可以在實際使用過程中自由添加和删除而不影響其他resource。即一個module盡可能叙述1-2件事情,如建立一個slb執行個體,并将一組ecs的挂載到這個slb下(slb的作用就是實作對ecs的負載均衡),至于slb的listener配置,應該放置在一個獨立的mudule中,一方面listeners比較複雜,涉及四種協定,另一方面,對于同一協定的listener,除了監聽端口外,大部分的配置都是相同的,而這些相同的配置可以通過一個單獨的module被複用在不同其他資源模闆中;
- 模闆編寫過程中,需要使用到大量的TF文法,詳見 configuration syntax interpolation syntax
- main.tf
- 每個 Module 都必須包含一個 main.tf 用于存放 resource 和 datasource。resource和datasource的參數禁止使用寫死,必須通過變量進行引用;
- 為了标準起見,每個 resource 和 data source 的命名均以一些關鍵字或者關鍵字字首為主,如
this
,盡量避免使用default
foo
test
- 為了更好的了解Module被他人引用的次數,阿裡雲Provider支援對每個Module進行打标,即在main.tf的provider中聲明字段configuration_source,格式如下:
provider "alicloud" { ... configuration_source = "terraform-alicloud-modules/demo" // This should be replaced by the specified owner and module name }
- variables.tf
- 每個變量都要添加該參數對應的描述資訊,這個資訊最終是要呈現在terraform registry官網上的;
- 對于一些非關系型的參數,可設定一個預設值,如name,description等
- 對于複雜類型的變量,要顯示聲明其類型,如list,map
- 子資源的變量要在Readme中以清單的形式予以呈現
- outputs.tf
- module中output的作用是被其他模闆和module引用,是以,每個module要講一些重要的資訊輸出出來,如資源ID,資源name 等;
- 重複資源的變量要以清單的形式予以輸出,如module ecs-instance中,建立多個instance資源,這些資源的ID應該輸出到一個list變量
中instance_ids
- 和variables一樣,子資源的output變量也要在Readme中以清單的形式予以呈現
- README
- 描述下目前Module是用來幹什麼的,涉及哪些resource和data source
- 增加
,指明該如何使用這個 Module。Module 的source 格式為Usage
,如:source = "<Repo Organization>/<NAME>/alicloud"
source = "terraform-alicloud-modules/slb-listener/alicloud"
- 添加module暴露的入參和出參,幫助開發者更好的使用Module
- 具體細節可參考其他module
為了更好地編寫Module,阿裡雲提供了一個
Module Demo,大家可以參考。
測試并釋出
在完成模闆的編寫後,可以通過
terratest來實作對目前Module的驗證性測試。測試無誤後,送出代碼到github。
如果想要把Module送出到阿裡雲官方組織
terraform-alicloud-modules,可直接在下方留言或者發郵件到 [email protected] 進行申請。申請通過後,我将為大家建立一個屬于自己的Repo。每個貢獻Module的開發者都将有機會成為terraform-alicloud-modules members中的一員。
由于Terraform Module 是以 Repo releases 來實作版本控制的,是以在确定代碼無誤後,包括Readme,釋出一個新的Release。之後在terraform module 注冊和完成module的釋出,具體操作詳見
registry modules.