天天看點

開發者實驗室教程—— Terraform init 如何加速

開發者實驗室教程—— Terraform init 如何加速

前言

Terraform

是開源的,用于資源編排管理的自動化工具。 Infrastructure as Code ,以代碼的形式将所要管理的資源定義在模闆中,通過解析并執行模闆來自動化完成所定義資源的建立、變更和管理。

相信絕大多數雲上使用者對其已經不再陌生,并且越來越多的公司和開發者已經開始使用 Terraform 來編排管理他們的雲資源基礎設施。更多的 Terraform 使用,我們可以參考

玩轉阿裡雲 Terraform 系列文章

其中 Terraform 提供了很多

Providers

供使用者使用,當然也包括

阿裡雲 Provider

。Terraform 通過 Provider 來完成對基礎設施資源的管理。不同的基礎設施提供商都需要提供一個 Provider 來實作對自家基礎設施的統一管理。目前,Terraform 累計提供了超過 200 個 Providers。是以 Terraform 可以通過一緻的流程以及 Provider 機制來幫助使用者進行高效便利的多雲管理。

我們編寫 Terraform 模闆,配置了 Provider,定義好編排配置後,第一步一定是執行

terraform init

指令,來初始化一些後續操作需要用到的設定和資料,包括自動下載下傳我們使用到的 Provider。

但是對于國内使用者來說,由于 Terraform Provider 并沒有國内源,是以 terraform init 時下載下傳 Provider 就成了耗時嚴重的環節,随便一個 Provder 動辄 3 分鐘以上的下載下傳時間,嚴重影響了我們的效率,更不要說一個完整的 Terraform 模闆可能需要用到多個 Provider 了。

是以,我們需要考慮如何加速 terraform init,即加速 Provider 的下載下傳。

目前阿裡雲 Cloud Shell 已經進行了 terraform init 的加速,原來動辄數分鐘的 init 過程現在隻需要幾秒中。同時我們可以在 Cloud Shell 中直覺的體驗 Terrafrom 的教程: 使用 Terraform 管理雲資源

Provider Cache

預設情況下,

terraform init

會将 Provider 下載下傳到目前工作目錄的子目錄

.terraform/plugins/

中,以便保證每個工作目錄都是獨立的。我們可以開始 Provider 的緩存,Provider 會優先讀取緩存,緩存沒有命中的才會進行下載下傳,保證每個相同版本的 Provider 隻會下載下傳一次。

開啟方式有兩種,我們可以修改 Terraform 的配置檔案,在配置檔案

~/.terraformrc

中增加

plugin_cache_dir

的設定。

plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"           

或者通過環境變量的方式來進行設定。

export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"           

需要注意的是,緩存目錄必須存在,Terraform 不會為我們自動建立目錄,是以不存在的話需要自行建立。同時,一旦 Provider 進行緩存,Terraform 不會自行删除它。随着 Provider 的更新,老的未使用的版本我們可能需要手動删除。

使用緩存可以極大的解決我們後續使用時的速度問題,但是一旦需要使用新的 Provider,或者更新 Provider,首次的下載下傳時間依然很慢,不論是 Terraform 自動下載下傳,還是我們手動下載下傳然後放到緩存目錄中。尤其是多人協作的雲端環境中,提升執行速度的同時,還要兼顧 Provider 更新的及時性。

設定 Provider Host

另一種比較 Hack 的方式,是設定 Provider Host。首先我們需要了解 terraform init 時,下載下傳 Provider 的流程。

開發者實驗室教程—— Terraform init 如何加速

可以看到 Terraform 會通過請求

https://registry.terraform.io/v1/providers/-/

${provider}/versions 擷取 Provider 的版本資訊,以 Aliyun Provider 為例,

請求結果

為:

{
  "id": "hashicorp/alicloud",
  "versions": [
    {
      "version": "1.17.0",
      "protocols": ["4"],
      "platforms": [
        {
          "os": "linux",
          "arch": "amd64"
        },
        ...
      ]
    },
    ...
  ]
}           

如果我們指定的 Provider 版本存在(沒有指定,則取最新的版本),Terraform 會請求

https://registry.terraform.io/v1/providers/hashicorp/

${provider}/${version}/download/${os}/${arch} 擷取該版本的資訊。以64 位 linux 系統上的 Aliyun Provider 1.58.1 為例,

{
    "protocols": ["4.0","5.0"],
    "os": "linux",
    "arch": "amd64",
    "download_url": "https://releases.hashicorp.com/terraform-provider-alicloud/1.58.1/terraform-provider-alicloud_1.58.1_linux_amd64.zip",
    "shasums_url": "https://releases.hashicorp.com/terraform-provider-alicloud/1.58.1/terraform-provider-alicloud_1.58.1_SHA256SUMS",
    "shasums_signature_url": "https://releases.hashicorp.com/terraform-provider-alicloud/1.58.1/terraform-provider-alicloud_1.58.1_SHA256SUMS.sig",
    "shasum": "f1af67c5bc068960f1726fe43bb8c2bd485140274fbe4e036dc52d50a7da329f",
    "signing_keys": {
        "gpg_public_keys": [
            {
                "ascii_armor": "...",
                "source": "HashiCorp",
                "source_url": "https://www.hashicorp.com/security.html"
            }
    ]
  }
}           

其中包含 Provider 和 shasum 的下載下傳位址。Terraform 會通過傳回的下載下傳位址下載下傳 Provider,同時通過 shasum 校驗檔案完整性。

是以,我們可以将從 registry.terraform.io 這個 Provider Host 擷取 Provider 元資訊的請求指向我們自己的 Provider Service,然後在 Terraform 擷取指定版本 Provider 資訊時,将 Provider 的下載下傳位址

download_url

修改為我們自己維護的 Provider 下載下傳源,配合 Provider Cache,保證任何時候,terraform init 都可以快速的執行。

Terraform v0.12 已經提供了修改 Provider Host 的方式,修改配置檔案

~/.terraformrc

,增加配置:

host "registry.terraform.io" {
    services = {
      "modules.v1" = "http://your-mirror.example.com/v1/modules/",
      "providers.v1" = "http://your-mirror.example.com/v1/providers/"
    }
  }           

如此,就可以将原本請求 registry.terraform.io 擷取 Provider 元資訊的請求,修改為請求我們自己的服務。

需要注意的是,modules.v1 需要同時顯示定義,如果你不想修改它,則可以繼續設定為官方的

https://registry.terraform.io/v1/modules/

我們可以通過阿裡雲的

函數計算

作為我們的自定義的 Provider Service,函數計算提供了

HTTP 觸發器

,讓我們的函數服務對外提供 HTTP 服務。同時我們可以使用 OSS 作為我們自己的 Provider 鏡像源,然後定時同步官方的 Provider 到我們的

OSS

中,保證 Provider 的持續更新。其中我們可以使用

邏輯編排

來輕松的編排我們的同步任務。

最後

已經進行了 terraform init 的加速,原來動辄數分鐘的 init 過程縮短到了幾秒鐘。同時你還可以通過教程學習如何

繼續閱讀