Terraform 工作流程:合併前應用 vs 合併後應用

如果您曾經管理過雲基礎設施, 您可能遇到過 Terraform, 這是該領域最流行的基礎設施即代碼工具。2023 年, Hashicorp 配置語言 (HCL) 再次成爲 GitHub 年度 Octoverse 報告 [1] 中增長最快的語言之一, 同比增長 36%。

隨着採用率的提高, 團隊一次又一次地面臨同樣的問題:

" 我們應該在將拉取請求合併回主分支後運行 terraform apply, 還是在合併之前運行?"

在本文中, 我們將研究這兩種不同的方法, 並回生命的終極問

關於 Terraform 的有狀態性質

基礎設施即代碼工具 (如 Terraform 和 OpenTofu) 的 CI/CD 與用於應用程序的管道不同, 因爲 Terraform 嚴重依賴於狀態, 該狀態描述了最新部署(由 terraform apply 觸發) 的結果。

將 Terraform 和 OpenTofu 中的狀態視爲單一事實來源, 其中包含所有信息, 如配置和元數據, 以及敏感值, 如雲基礎設施的機密。

團隊通常使用 遠程後端 [2] , 如 AWS S3 或 Google Cloud Storage, 來對狀態文件進行版本控制、安全保護和加密。

與其他可以獨立並行運行的 CI 管道不同, Terraform 的 CI 管道可以讀取和修改狀態。這使得它們在使用單個狀態文件時不適合並行化。

以下是有關 Terraform 中狀態及其影響的一些事實:

Terraform 的有狀態性質使得每次運行 terraform apply 都可能依賴於任何其他運行。這意味着, 與傳統的 CI 不同, 每個管道都可以獨立並行運行, Terraform 管道通常按順序運行, 因此是阻塞的 (一次只能運行一個調用 terraform apply 的工作流)。

Terraform 工作流程

現在我們知道 Terraform 管道必須按順序運行, 讓我們來研究兩種最常見的工作流程。

合併後應用

這個工作流程確保主分支始終反映基礎設施的期望狀態。目標是在這個期望狀態和已部署資源的實際狀態之間達成 1:1 的映射。

工作流程

  1. 打開引入一些更改的 PR。

  2. CI/CD 管道檢查代碼的正確性 (例如 terraform fmt、 terraform validate、 terraform test), 運行測試和第三方工具 。[3] 它還爲每次提交生成一個可供審閱者查看的計劃 terraform plan

  3. 審閱者審查代碼, 請求更改或批准拉取請求。

  4. 一旦拉取請求合併回主分支, 管道就會應用步驟 2 中創建的最新審查過的計劃, 以準確部署審閱者批准的更改。

優點

缺點

合併後應用 工作流程的美妙之處在於其簡單性。在大多數通用 CI/CD 提供商 (如 GitHub Actions、GitLab CI/CD、BitBucket Pipelines 等) 中, 無需額外的基礎設施或工具即可配置此工作流程。

問題所在:不穩定的應用

應用後合併工作流程的最大缺點是,大多數 Terraform 錯誤在計劃階段是不可見的。例如,在運行應用時經常會遇到權限問題、錯誤配置或達到配額等邊緣情況,這些在計劃階段無法捕獲。

原因是許多提供商無法在應用更改之前進行深入驗證。例如,AWS 提供商大多能夠在嘗試應用 S3 存儲桶之前驗證其配置是否正確;但是,提供商無法知曉您的 AWS 賬戶中配置的任何阻止創建公共存儲桶的策略。如果存在這樣的策略,應用將失敗。

這常常給團隊一種錯誤的信念,認爲看似準備好合併的拉取請求將毫無問題地部署,只是在點擊合併按鈕後纔不愉快地感到驚訝。

這些可能性使應用階段成爲工作流程中不可預測的部分。例如,當應用失敗時,唯一的修復方法是在網絡問題(如超時)的情況下重新運行管道,或打開新的拉取請求以修復錯誤配置。這會讓開發人員再次經歷整個循環,可能會耗費時間並影響開發人員的神經。

合併前應用

不穩定的應用是一些團隊採用 "合併前應用" 工作流程的主要原因,允許他們在拉取請求中通過評論或任何其他觸發器在將更改合併回主分支之前應用更改。

這在需要時處理 PR 中的失敗,然後將新的基礎設施代碼合併到默認分支中。它承諾保持主分支的整潔,沒有迭代步驟的雜亂。

工作流程

  1. 打開引入一些更改的 PR。

  2. CI/CD 管道檢查代碼的正確性(例如 terraform fmt、 terraform validate、 terraform test),運行測試和第三方工具。它還爲每次提交生成一個 terraform plan,供審閱者查看。

  3. 審閱者查看代碼更改和計劃文件。

  4. 審閱者或作者在 PR 內觸發應用(可選擇經常創建新計劃也可以觸發)。

  5. 管道從步驟 2 獲取持久化的計劃文件,並使用先前生成的計劃文件運行 terraform apply

  6. 一旦 terraform apply 成功運行,PR 就會合併到主分支中。

優點

缺點

雖然 "合併前應用" 承諾解決不穩定應用的問題,但它帶來了額外的複雜性和成本。這意味着每當您想從拉取請求內應用更改時,您將面臨一系列全新的問題需要解決:

開源和商業供應商如 Atlantis[4] 、 Digger[5] 和 Terrateam[6] 存在,提供工具來克服這些挑戰,具有 PR 級鎖定、自動計劃和自動合併等功能。

雖然有工具可以解決複雜工作流程引入的問題很好,但是否應該考慮 "合併前應用" 工作流程仍然值得爭議。

何時使用合併後應用與合併前應用

所以現在我們已經瞭解了 apply-after-mergeapply-before-merge 工作流程的區別, 應該使用哪一個呢? 請看以下比較, 以詳細瞭解基於您的環境的潛在影響:

基於上述事實, 我們認爲大多數團隊應該使用 apply-after-merge 工作流程, 因爲它易於採用和管理, 衝突的可能性較小, 不需要額外的工具, 並確保主分支始終作爲單一的事實來源!

單體狀態的問題

apply-before-merge 往往在單體和大型狀態文件中更有問題。例如, 如果您使用 apply-before-merge, 引入對單個 Terraform 狀態更改的單個 Pull Request 將鎖定所有其他使用稱爲 PR 級鎖定的概念的 Pull Request, 以避免衝突。因此, 團隊在處理單體狀態文件時只能一次處理一個 Pull Request。

除非您將狀態拆分爲多個較小的狀態文件, 否則像 apply-before-merge 這樣的工作流程很有可能會阻礙您的工程速度。

事實上, 拆分狀態被認爲是最佳實踐 [7] , 可以限制影響範圍, 加快 CI/CD 運行時間, 並在處理大型 IaC 代碼庫時實現更好的協作。

額外收穫: 通過查看 5000 個真實 IaC 部署學到的經驗

在 Terramate, 我們與客戶密切合作, 以確定最適合他們需求的工作流程。總的來說, 我們的團隊已經審查了超過 5000 個 Terraform 部署, 趨勢很明顯: apply-before-merge 更有可能在長期內造成問題並減慢團隊速度, 更不用說需要額外工具帶來的複雜性了。

使用 apply-before-merge 策略, 更改可能在 Pull Request 中多次成功應用, 這給人一種虛假的穩定感。在任何時候, main 分支中看似穩定的代碼都可能因外部數據源 (如 SSM 參數) 或不太嚴格的版本固定而中斷。因此, 無論您如何合併, 識別故障 (例如, 通過漂移檢測) 都是至關重要的。通過實施 apply-after-merge, 可以大大降低引入循環的可能性。

總結本文, 這裏有一個關於 豐田生產系統 [8] "安燈繩" 的軼事。在九十年代, 豐田擁有世界上最高效的汽車工廠。其他汽車製造商的高管參觀了生產設施, 無法相信每個在裝配線上工作的人都可以關閉整個系統——這是多麼浪費生產力啊。

但實際上, 關閉整個系統, 識別問題並一次解決一個, 是保持裝配線順利運行的關鍵成功因素之一。同樣的原則也適用於基礎設施即代碼的工作流程。如果主分支不穩定, 絕對必須首先解決, 並識別和解決根本原因。

當您 apply-after-merge 時, 上述問題就不會發生。合併的代碼會被應用, 您會有一個很好的、有序的事件序列。

總結

在本文中, 我們瞭解了 Terraform 和 OpenTofu 中可用的不同工作流程。本文的主要要點是, 簡單性是可靠性和穩定性的關鍵驅動因素, 這就是爲什麼團隊應該專注於採用 apply-after-merge 來管理他們的 IaC 部署。

如果您一直堅持到最後, 謝謝您。如果您有興趣瞭解如何使用通用 CI/CD 系統設置 apply-after-merge 管道, 我們建議您查看我們的 Terraform 和 OpenTofu CI/CD 藍圖 [9] , 這是一系列預配置的生產級工作流程, 用於在 GitHub Actions[10] 和 GitLab CI/CD[11] 中採用 apply-after-merge 工作流程。每個藍圖都帶有預配置的預覽部署漂移檢測管道, 可幫助您快速啓動和運行 Terraform 和 OpenTofu 自動化!

此外, 我們很想了解您正在使用的工作流程以及原因。歡迎加入我們的 Discord 社區 [12] 並分享您的設置詳情。

參考鏈接

  1. Octoverse 報告: https://github.blog/2023-11-08-the-state-of-open-source-and-ai/
  2. 遠程後端: https://developer.hashicorp.com/terraform/language/settings/backends/remote
  3. 。: http://tooling.it/
  4. Atlantis: https://www.runatlantis.io/
  5. Digger: https://digger.dev/
  6. Terrateam: https://terrateam.io/
  7. 拆分狀態被認爲是最佳實踐: https://terramate.io/rethinking-iac/why-you-should-break-down-your-terraform-into-stacks/
  8. 豐田生產系統: https://www.sixsigmadaily.com/what-is-an-andon-cord/
  9. Terraform 和 OpenTofu CI/CD 藍圖: https://terramate.io/docs/cli/automation/
  10. GitHub Actions: https://terramate.io/docs/cli/automation/github-actions/
  11. GitLab CI/CD: https://terramate.io/docs/cli/automation/gitlab-ci/
  12. Discord 社區: https://terramate.io/discord
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/dvcxnWFmjPiS2QG9POk-2A