在terraform 的設定中,都會被定義一個backend。通常如果沒有特別設定,就會是local。在使用local的情況下,我們的tfstate就會被直接被存放在terraform configuration的目錄下。大家應該有發現,執行完 terraform apply 後,就會多出一個 terraform.tfstate 的檔案。

但如果今天,我會建立出兩個環境,分別是Staging與Production。而這兩個環境都會建立出一模一樣的Infrastructure。這樣的情境下,我要直接複製這個資料夾,並分別取名為Staging與Production,然後分別管理嗎?

有沒有一個方法是,我在同一個資料夾中,可以很輕易的佈署到不同的環境?

當然是有的,也就是今天的主題:「Workspace」。

Photo by Shridhar Gupta on Unsplash

Workspaces

程序剛剛的話題,在某些的情境下,我們可能只需要修改一小部分的code,舉例來說: 今天我打算建立出兩個環境出來

  1. 建立一個e2-medium 的GCE這個當作Production
  2. 建立一個 e2-micro的GCE這個當作Staging

在這情況下,我們可能會直接將terraform configuration資料夾複製一份,改個資料夾名稱後,重新apply。這時候的檔案結構可能就會長像這樣。

|--- Production
|--- main.tf
|--- variables.tf
|--- terraform.tfstate
|--- Staging
|--- main.tf
|--- variables.tf
|--- terraform.tfstate

有著差不多的terraform configuration,但修改了一小部分的code,在這邊唯一不同的點就是建立GCE的 machine_type ,因為一小部分的修改就要將其他的程式碼也都重複貼上的話,似乎就比較沒效率了些,為了應付這個情況,我們可以考慮藉由判斷 terraform 不同的workspaces來做處理。

在不同的workspace中,彼此會有著不同的tfstate。會變成以下的儲存方式。

|--- GCE_project
|--- main.tf
|--- variables.tf
|--- terraform.tfstate.d/
|--- Production
|--- terraform.tfstate
|--- Staging
|--- terraform.tfstate

而terraform跟workspace的command存在於terraform workspace 的分支下,我們老樣子可以先求救一下。

$ terraform workspace --helpUsage: terraform [global options] workspacenew, list, show, select and delete Terraform workspaces.Subcommands: 
delete Delete a workspace
list List Workspaces
new Create a new workspace
select Select a workspace
show Show the name of the current workspace

我們看到workspace總共支援了五種Subcommand,每一個功能其實都蠻重要的。

建立workspace

$ terraform workspace new <New_workspace_name>

列出workspace

$ terraform workspace list

切換workspace

$ terraform workspace select <Workspace_name>

取得當前workspace

$ terraform workspace show

刪除workspace

$ terraform workspace delete <Workspace_name>

正在使用中的workspace是不能刪除的

聽到這邊你可能會覺得好像還是少了些什麼?雖然我有不同的Workspace可以在同一個Project中存放不同的tfstate,但我每次要佈署的時候都要去修改對應的位置嗎?這樣好像也不是這麼的方便。

Photo by Afif Kusuma on Unsplash

Conditions Expressions

其實我們是可以在code中取得目前是哪一個workspace的,為了讓我可以更方便的去操作,我需要在code中加入判斷式去判斷目前的workspace!讓 machine_type 可以隨著我的workspace不同而自動修改成不同的值。

resource "google_compute_instance" "example" {
name = "workspace-example"
machine_type = "${terraform.workspace == "Production" ? "e2-medium" : "e2-micro"}"
zone = "us-central1-a"
...
}

增加判斷式後,重新執行 terraform apply 就可以看到machine_type可以隨著Workspace做改變囉!

Summary

在實務上,如果沒有特別的預算考量,會希望Staging和Production的環境能夠越一致越好。如果使用Terraform來做佈署,差不多的程式碼卻又分成兩個project來管理,其實是會讓人覺得有點多餘的。除了程式碼的高重複性外,還必須要多耗費硬碟空間去儲存兩個差不多的Project terraform init下載的套件。藉由Workspace就可以讓單一個Project可以解決需要佈署多個環境的問題。

時不時會與大家分享工作上遇到的事情,或是最近研究了哪些技術。也很歡迎大家按讚訂閱 Facebook

感謝您的閱讀

--

--

身為DevOps工程師

目前在蓋亞資訊擔任DevOps Consultant。最近才從後端的世界轉成投向DevOps的懷抱,目前專注在Kubernetes, GitLab, DevSecOps的學習中。