
前言
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 會通過請求
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 過程縮短到了幾秒鐘。同時你還可以通過教程學習如何