昨天聊到 Provider,大家應該有注意到,像是 GCP 專案 ID、區域、認證檔案這些東西,如果直接寫死在程式碼中,其實很不方便!
一來切換環境很麻煩,二來敏感資訊也不適合直接暴露。
所以今天要來分享 Variables 的具體用法,讓我們的配置可以更彈性也更安全~
🐈🐈🐈
在前幾次練習中我們在配置 Provider 時,幾乎都是這樣寫的:
provider "google" {
project = "my-gcp-project"
region = "asia-east1"
credentials = file("account.json")
}
這樣會有幾個問題產生:
這就是 Variables 的用武之地了!接下來我們來看看要怎麼使用 Variables 來讓配置更有彈性。
我們在 variables.tf
定義變數時,可以先給一個預設值,例如:
variable "region" {
type = string
default = "asia-east1"
}
當沒有指定值的時候,Terraform 就會使用 default~
var
參數傳入值terraform.tfvars
檔案中定義TF_VAR_region
如果變數沒有設定 default
,執行 terraform 指令時就會要求你手動輸入值,或是出現錯誤提示。預設值的優先順序最低,所以當有透過其他方式指定值,就會覆蓋掉預設值唷!
💡 小提醒
variables.tf
和terraform.tfvars
是兩個不同的檔案喔!前者是「定義變數」,後者是「給變數賦值」。
上面提到預設值的優先順序最低,那完整的優先權是怎樣呢?Terraform 會按照以下順序尋找變數值:
var
(最高優先權)terraform.tfvars
或 .tfvars
檔案TF_VAR_*
default
(最低優先權)假設我們有相同的 region
變數,依照上面提到的優先權順序:
variables.tf
variable "region" {
type = string
default = "asia-east1" # 優先權 4
}
terraform.tfvars
region = "us-central1" # 優先權 2
執行指令時
terraform apply -var="region=europe-west1" # 優先權 1
結果:最後會使用 europe-west1
,因為 CLI 參數的優先權最高!
這個機制讓我們可以靈活地在不同情況下覆蓋變數值,非常適合多環境部署。
有些東西(像 DB 密碼、API Key),會不想在執行 plan
或 apply
時被顯示出來。這時候就可以設定 sensitive,Terraform 就會幫我們把這些隱藏起來。
variable "db_password" {
type = string
sensitive = true
}
這樣在輸出時就會變成 (sensitive value)
。
⚠️ 不過要注意,這只是「遮起來」,並不是加密!!!真正的安全還是要靠外部的 Secret Manager。
用變數只是「不要硬寫在程式碼裡」,但值總要有地方放吧?這邊幫大家整理常見做法大概有這幾種:
做法 | 儲存位置 | 適合場景 | 注意事項 |
---|---|---|---|
.tfvars 檔 |
terraform.tfvars 、dev.tfvars |
個人練習、小專案 | 記得 .gitignore |
環境變數 | TF_VAR_xxx |
本地測試、CI/CD | .env + CI Secret 很好搭配 |
Secrets Manager | GCP/AWS/Vault | 正式專案 | 集中管理、IAM 控制,安全性最佳 |
CI/CD Secret | GitHub Actions / GitLab CI | 自動化部署 | 跟 pipeline 整合最方便 |
變數的另一個大好處,就是環境切換變得簡單很多!
我們就可以這樣來區分檔案:
dev.tfvars
project_id = "dev-project"
region = "asia-east1"
credentials_file = "dev-account.json"
stage.tfvars
project_id = "stage-project"
region = "asia-east2"
credentials_file = "stage-account.json"
這樣在執行 apply
時就很簡單:
terraform apply -var-file="dev.tfvars"
terraform apply -var-file="stage.tfvars"
同一份程式碼,就能跑不同環境了 ✨
只要能夠好好運用 Variables 並透過合理的變數設計,就可以達到:
雖然今天的例子主要示範 Provider,但其實 Variables 在 Terraform 裡能應用在任何地方,例如 Resource 或 Module 喔~