天天看點

Terraform Module 編寫指南

Module 是一個Terraform 模闆,是對多個子節點,子資源,子架構模闆的組合和抽象。利用Module 在降低模闆編寫和維護複雜度的同時,使得模闆結構更加簡潔清楚。為什麼要使用 Module,詳見文章 Module 讓 Terraform 使用更簡單

本文将根據自己對 Module 的了解,向大家講解如何編寫一個通用,标準的 Module。

建立 Module 的 Github 倉庫

在 Terraform 官方注冊 module,目前隻支援 Github 的倉庫,是以,在編寫模闆之前,必須先建立一個

标準的 Github 倉庫

  1. 倉庫必須是 Public 的;
  2. 倉庫名稱必須符合格式:

    terraform-<PROVIDER>-<NAME>

    ,如

    terraform-alicloud-ecs-instance

    terraform-alicloud-vpc

  3. 倉庫建好後必須給倉庫添加一個描述

為了更好的管理所有阿裡雲的terraform module,現在所有的倉庫都建在組織

terraform-alicloud-modules

下。當有建立倉庫需求時,可聯系負責人。

編寫Module

Module 倉庫建立完畢後,首先要 fork 倉庫并将其clone到本地。接下來,開始 Mudole 的編寫工作。官方已經給出了一個标準的 Module 應該遵循的原則和規範,詳見

standard-module-structure

. 本文将在此基礎上進行補充。

  1. 基本原則
    • 每個Module不宜包含過多的資源,要盡可能隻包含同一産品的相關資源,這樣帶來的好處是Module的複雜度不高,便于維護和閱讀;
    • 對于統一産品的不同資源,應該分别放在不同的子module中,然後在最外層的main.tf中組織所有的子資源,比如 module slb 中定義了兩個資源

      slb instance

      slb attachment

      ,這兩個子資源分别定義在了

      modules/slb

      modules/slb_attachment

      中,然後在最外層的

      main.tf

      中将這兩個module組合為一個新的module
    • 每個module要盡可能單元化,以便可以在實際使用過程中自由添加和删除而不影響其他resource。即一個module盡可能叙述1-2件事情,如建立一個slb執行個體,并将一組ecs的挂載到這個slb下(slb的作用就是實作對ecs的負載均衡),至于slb的listener配置,應該放置在一個獨立的mudule中,一方面listeners比較複雜,涉及四種協定,另一方面,對于同一協定的listener,除了監聽端口外,大部分的配置都是相同的,而這些相同的配置可以通過一個單獨的module被複用在不同其他資源模闆中;
    • 模闆編寫過程中,需要使用到大量的TF文法,詳見 configuration syntax interpolation syntax
  2. 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
      }           
  3. variables.tf
    • 每個變量都要添加該參數對應的描述資訊,這個資訊最終是要呈現在terraform registry官網上的;
    • 對于一些非關系型的參數,可設定一個預設值,如name,description等
    • 對于複雜類型的變量,要顯示聲明其類型,如list,map
    • 子資源的變量要在Readme中以清單的形式予以呈現
  4. outputs.tf
    • module中output的作用是被其他模闆和module引用,是以,每個module要講一些重要的資訊輸出出來,如資源ID,資源name 等;
    • 重複資源的變量要以清單的形式予以輸出,如module ecs-instance中,建立多個instance資源,這些資源的ID應該輸出到一個list變量

      instance_ids

    • 和variables一樣,子資源的output變量也要在Readme中以清單的形式予以呈現
  5. README
    • 描述下目前Module是用來幹什麼的,涉及哪些resource和data source
    • 增加

      Usage

      ,指明該如何使用這個 Module。Module 的source 格式為

      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

.

繼續閱讀