Terraform 的使用帶來的變化
Terraform 最直觀的功能就是 Infrastructure as Code,將雲上基礎設施以代碼的形式描述出來,那麼每一個基礎設施的詳細參數都是清楚、明確的,可以很快的通過複製代碼修改個別參數的方法創建出同類資源,標準且提效。
同時,Terraform 進行與雲廠商交互操作的時候是非常嚴謹,在你更改完代碼後,需要先用 terraform plan 進行變更預覽,你可以看到你的更改會影響到線上的部分,確定後進行 terraform apply,一次變更塵埃落定。
使用 Terraform 後需要注意的就是 code repo, 存儲線上基礎設施狀態的 backend,最重要的就是 plan 之後的 review。Terraform 使用的語言是Hashicorp 自己定義的 HCL 語言,是屬於一種使用不難但是入門需要費點功夫的語言,要求所有研發都會寫是不必要也不現實的。同一個 repo 裡面的東西,如果面向所有人,必將帶來混亂的目錄結構與定量定義,所以基礎設施的維護還是要放在基礎設施工程師這裡,然而專人負責寫 Terraform 也大可不必,於是我們就把它做成了一個流程化的東西。
Terraform 在流利說的流程化
resource "alicloud_instance" "instance" { availability_zone = "cn-beijing-b" security_groups = alicloud_security_group.group.*.id
instance_type = "ecs.n4.large" system_disk_category = "cloud_efficiency" system_disk_name = "test_foo_system_disk_name" system_disk_description = "test_foo_system_disk_description" image_id = "ubuntu_18_04_64_20G_alibase_20190624.vhd" instance_name = "test_foo" vswitch_id = alicloud_vswitch.vswitch.id internet_max_bandwidth_out = 10 data_disks { name = "disk2" size = 20 category = "cloud_efficiency" description = "disk2" encrypted = true kms_key_id = alicloud_kms_key.key.id }}看起來好像很容易看懂但有的地方又有點疑惑,接著就要去查 alicloud provider documentation 各個參數的意思然後改參數,對於一個沒有寫過 Terraform 的人來說還是比較麻煩的。而做了一個前端申請頁面後,只需要選擇必定的參數,Luban 後端就會按既定的規則在相應目錄下進行代碼生成並觸發 GitOps 流程,對於申請人來說,只需要等審批結果了。mobius 是 Luban 後端非常重要的一個引擎,它能夠集成 GitLab 的 webhook, 處理 merge request 的 create/update/merge/cancel 事件,能夠處理 Terraform 流程的 int/plan/apply, 並輸出日誌。git 提交後,mobius 會自動進行 terraform plan 的 Pipline。TechLeader 通過前端的申請歷史,可以看到對應資源申請的詳細進展,查看 plan 結果是否符合預期,符合點擊 approve 進入下個流程,由基礎設施成員進行覆審。值班人員在 GitLab 上審批 approve 後觸發mobius webhook 進行 terraform apply 即對線上做出變更,apply 成功後,mobius 自動進行代碼 merge, 至此一個申請流程結束,而申請人也會在內部Chat上收到 Luban Bot發出的資源申請成功的通知。如此,資源的申請就非常的嚴謹,也不需要人員專門去學習寫 Terraform, 重點就放在 review terraform plan 輸出的變化是不是符合預期,並且通過ChatBot的觸發性通知,提升了效率。Terraform 的導出如果之前未使用 Terraform ,是直接點出來的資源,然後現在想接入 Terraform 進行管理,不用擔心,HashiCorp 公司做的 Terraform 適用於各個雲廠商,當然會考慮到這種情況,對於已有的 resource,terrafrom import 可以解決這個問題,把線上的資源同步 到 backend 裡的 tfstate 中,同時可以查看到對應 tf 文件是什麼,如此,只要進行 import 操作,然後把相應的 tf code push 到 GitLab 的repo 裡,當看到 terraform plan 的結果是 「No changes」,那麼導出就結束了。但是對於大批量的導出來說,按官方方法一個個導出是一個非常費時費力的事情,在 GitHub 搜尋過後,果然發現了一個開源的項目 「Terraformer」,可以一次性導出所有資源,也可以按 filter 進行導出部分資源,但直接用對於我們理想的目錄結構與資源取名來說顯然是不適用的,如此,就需要在它的基礎上進行流利說導出適配。Terraformer 批量導出原來的 Terraformer 會把資源的 tf 文件與應該存儲在雲上 backend 的 tfstate 全部導出到本地,所有資源按照資源類型劃分目錄,同種資源放在同一個 tf 文件裡,所有導出的資源名都是採用某個參數按他的命名規則 format取的,非常的長且不易讀,而按我們的 repo 管理,所有的資源是按 app 的目錄進行劃分,把 app 相關資源放在一起,無法按 app 劃分的底層網絡相關資源一起放在一個叫 shared 的目錄裡,並按資源類型進行更細節的目錄劃分,而資源的命名也很易讀,那麼需要做的事就很清楚了:
把相關資源按 app 導出到不同的目錄
更改導出資源的name, tf 與 tfstate 需要對應更改
把tfstate 上傳到雲上 backend 存儲(對象存儲 OSS)
把 tf 文件 push 到 GitLab 的 repo 裡
進行 terraform plan 看結果是不是 「No changes」
當寫完適配程序,進行批量導出,只需要填寫一張表,需要導出的資源類型,篩選資源的 filter,導出目錄,資源名(按 filter 生成或直接指定),然後轉化成一個 csv 文件,就可以一鍵進行導出了。
總結
優勢明顯
容易重現的系統。能夠毫不費力且可靠地重建基礎設施中的任何元素。
可任意處理系統。可以輕鬆創建、銷毀、替換、更改以及移動資源。
一致的系統。假設兩個基礎設施元素提供相似的服務,比如同一個集群中有兩個應用程式伺服器。這些伺服器應該幾乎完全相同。它們的系統軟體和配置應該是一樣的,除了一丁點配置(比如IP位址)用於區分彼此。
可重複的過程。基於可再生原則,對基礎設施執行的任何行為都是可以重複的。
變化的設計。確保系統能夠安全地改變。
依靠一個標準化的工作流,同時憑藉 Terraform 非常好的可 Review 變更的機制,同時使用一套前端工作流配合 GitLab 現有的 code review 行為,大大避免了基礎資源變更導致的異常且可追溯。解決了線上基礎資源雜亂無標準、無法複製行為的痛點。並結合一系列自動化轉化器和串聯工具的開發把現有的標準化直接輸出。做到了在未來多雲管理上的標準化、可複製、可追溯的工程化落地。為一鍵拉起一朵雲奠定了基礎。
作者簡介
楊海燕 技術部 cloud-infra 團隊 後端工程師