大 module 小 module,能夠重複使用又好維護的就是好 module
上一章介紹 module 的基本原理,然而並沒有說明實務上如何實踐。另外,本地 module 開發上還有一些問題,例如檔案分享,與版本鎖定。
本章會講解遠端的 module,以及實務上 module 的開發流程
課程內容與代碼會放在 Github 上: https://github.com/chechiachang/terraform-30-days
賽後文章會整理放到個人的部落格上 http://chechia.net/
上一章使用的範例,module source 都是本地檔案的路徑,透過路徑去找到本機上的 module,稱為 local-path
module "registry" {
for_each = toset(local.environments) # convert tuple to set of string
source = "../../..//azure/modules/container_registry"
#source = "/Users/che-chia/my-workspace/terraform-30-days//azure/modules/contrainer_registry"
...
}
除了 local path 以外,最常使用的是 Git
Git remote module 原理非常簡單,在 init 的時候,使用 git 向遠端的 git repository 取得 module .tf 檔案,在本地的 .terraform 裡頭暫存一份,plan 的時候使用 .terraform 內的 module。source 設定參考 _poc/container_registry_module_remote
module "registry" {
for_each = toset(local.environments) # convert tuple to set of string
source = "git::ssh://git@github.com/chechiachang/terraform-30-days.git//azure/modules/container_registry?ref=main"
#source = "git::https://git@github.com/chechiachang/terraform-30-days.git//azure/modules/container_registry?ref=main"
#source = "git@github.com:chechiachang/terraform-30-days.git//azure/modules/container_registry?ref=v1.0.0"
#source = "git@github.com:chechiachang/terraform-30-days.git//azure/modules/container_registry?ref=f1d8c86de3aebc40f16bc3a015f9a42b70dba209"
...
}
我們實際使用 _poc/container_registry_module_remote
來操作說明:
terraform init
Initializing modules...
Downloading git::ssh://git@github.com/chechiachang/terraform-30-days.git?ref=v0.0.1 for registry...
- registry in .terraform/modules/registry/azure/modules/container_registry
Downloading git::ssh://git@github.com/chechiachang/terraform-30-days.git?ref=v0.0.1 for test...
- test in .terraform/modules/test/azure/modules/container_registry
Initializing the backend...
...
Initializing provider plugins...
...
init 的時候,比起 local-path module,Terraform 額外執行 git clone,將 module 中的 source clone 到本地 .terraform 資料夾。照慣例進去開一下
tree -L 1 .terraform
.terraform
├── modules
├── providers
└── terraform.tfstate
2 directories, 1 file
cat .terraform/modules/modules.json | jq
{
"Modules": [
{
"Key": "test",
"Source": "git::ssh://git@github.com/chechiachang/terraform-30-days.git//azure/modules/container_registry?ref=v0.0.1",
"Dir": ".terraform/modules/test/azure/modules/container_registry"
},
{
"Key": "",
"Source": "",
"Dir": "."
},
{
"Key": "registry",
"Source": "git::ssh://git@github.com/chechiachang/terraform-30-days.git//azure/modules/container_registry?ref=v0.0.1",
"Dir": ".terraform/modules/registry/azure/modules/container_registry"
}
]
}
由於使用遠端的 module ,每次對 module 內杜設定有更改,都需要重新執行 terraform init,例如:
除了需要 init 下載以外,terraform plan && terraform apply 都與之前的使用完全一樣。
Pros
Cons
目前我們的 module 結構簡單,而且沒有額外依賴其他 module,所以缺點感覺不太出來。實務上許多複雜的 module 內部都還會有更多曾依賴的 module,每個 module 自己還有依賴的 providers,每次下載都需要時間,.terraform 都會變一大包
雖然說了缺點,然而這些小缺點並不影響開發,我們還是會選擇使用 remote module
Terraform 官方提供了 module 分享庫,稱為Terraform Registry,上面儲存許多 provider 與 modules
是的,當我們使用 provider {},預設都會到 Terraform Registry 上去下載 provider 的檔案。Terraform 官方在上頭維護許多 remote module,可以直接使用。
直接看例子:
我們可以使用 Terraform Registry: Azure/compute,來創建 Azure Compute VM,這個 module 除了 vm 以外,還包含常與 vm 共用的資源,例如 network interface,security group,public ip...等,貼近常見使用情境
azurerm_availability_set.vm
azurerm_network_interface.vm
azurerm_network_interface_security_group_association.test
azurerm_network_security_group.vm
azurerm_network_security_rule.vm
azurerm_public_ip.vm
azurerm_storage_account.vm-sa
azurerm_virtual_machine.vm-linux
azurerm_virtual_machine.vm-windows
random_id.vm-sa
使用上也非常方便,Terraform Registry 上多半會提供 Readme,範例,以及 input 的參數。
筆者個人比較少使用 Registry,筆者習慣直接看 Github 上的 .tf 程式碼,畢竟 provider 除了會將 module 上傳至 Terraform Registry 外,也會上傳到 Github,例如Github: Azure compute
各位可以依照自己使用習慣選擇。也許之後 Terraform Registry 會推出更多新功能,期待之後的改進會變得更好用。
Terraform 仍支援其他 remote module 如:s3, gcs...,筆者認為 git 還是最常使用的,而且其他類型 module 概念都類似,有需求的朋友可以依據需求嘗試使用其他 module。
理解 module 的基本原理與使用,接下來要說明實務中如何開發 module。
dev/southeastasia/container_registry
編輯 local-path modulestag/southeastasia/container_registry
)prod/southeastasia/container_registry
)module 是持續修改,很難一開始就寫出完美的 module。使用 terraform 來落實 infrastructure as code,可以在 infrastructure 中導入軟體開發流程,透過 gitflow,讓 instructure 方便測試,讓環境更穩定。
更多 Terraform IaC 的好處,我們在後面章節實際帶各位體會。
_poc/compute
NOTE:
Standard_B1s
免費的 vm size,詳請請見 Azure Free Plan 清單
resource_gropu_name
,location
,environment
... backend "azurerm" {
resource_group_name = "terraform-30-days"
storage_account_name = "tfstatee903f2ef317fb0b4"
container_name = "tfstate"
key = "container_registry_module.tfstate"
}
有沒有可能在更精簡,更方便? 我們介紹 Terragrunt