前言
在使用 Terraform 管理基礎設施時,我們經常需要針對不同環境(如開發、測試、正式環境)部署相同的基礎設施配置。Terraform Workspace 提供了一個優雅的解決方案,讓我們能夠在單一配置下管理多個環境的狀態。
Workspace 概念
什麼是 Workspace?
Terraform Workspace 是一種狀態隔離機制,允許你在同一個工作目錄中維護多組獨立的狀態檔案。每個 workspace 都有自己的 terraform.tfstate 檔案,這意味著你可以使用相同的 Terraform 配置來管理多個環境,而不會產生狀態衝突。
預設 Workspace
當你初始化 Terraform 專案時,會自動建立一個名為 default 的 workspace。如果你沒有明確建立或切換 workspace,所有操作都會在這個預設 workspace 中進行。
1
2
3
| # 查看目前所在的 workspace
terraform workspace show
# 輸出: default
|
建立與切換 Workspace
基本操作指令
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 列出所有 workspace
terraform workspace list
# 建立新的 workspace
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod
# 切換到指定的 workspace
terraform workspace select dev
# 刪除 workspace(需先切換到其他 workspace)
terraform workspace delete staging
|
實際操作範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 建立開發環境的 workspace
$ terraform workspace new dev
Created and switched to workspace "dev"!
# 確認目前的 workspace
$ terraform workspace show
dev
# 列出所有 workspace
$ terraform workspace list
default
* dev
# 星號表示目前所在的 workspace
|
多環境管理
在 Terraform 配置中,你可以使用 terraform.workspace 變數來取得目前的 workspace 名稱,並根據不同環境設定不同的資源配置。
1
2
3
4
5
6
7
8
9
10
| # main.tf
resource "aws_instance" "web" {
ami = var.ami_id
instance_type = terraform.workspace == "prod" ? "t3.large" : "t3.micro"
tags = {
Name = "web-server-${terraform.workspace}"
Environment = terraform.workspace
}
}
|
條件式資源部署
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 只在正式環境部署額外的監控資源
resource "aws_cloudwatch_metric_alarm" "high_cpu" {
count = terraform.workspace == "prod" ? 1 : 0
alarm_name = "high-cpu-utilization"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "2"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "120"
statistic = "Average"
threshold = "80"
}
|
變數區分
使用 Map 變數區分環境配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # variables.tf
variable "instance_type" {
type = map(string)
default = {
dev = "t3.micro"
staging = "t3.small"
prod = "t3.large"
}
}
variable "instance_count" {
type = map(number)
default = {
dev = 1
staging = 2
prod = 3
}
}
|
1
2
3
4
5
6
7
8
9
10
| # main.tf
resource "aws_instance" "web" {
count = var.instance_count[terraform.workspace]
ami = var.ami_id
instance_type = var.instance_type[terraform.workspace]
tags = {
Name = "web-server-${terraform.workspace}-${count.index + 1}"
}
}
|
使用獨立的變數檔案
另一種方式是為每個環境建立獨立的變數檔案:
1
2
3
4
5
6
7
8
| # 目錄結構
.
├── main.tf
├── variables.tf
├── outputs.tf
├── dev.tfvars
├── staging.tfvars
└── prod.tfvars
|
1
2
3
4
| # dev.tfvars
instance_type = "t3.micro"
instance_count = 1
enable_monitoring = false
|
1
2
3
4
| # prod.tfvars
instance_type = "t3.large"
instance_count = 3
enable_monitoring = true
|
1
2
3
4
5
6
| # 套用特定環境的變數
terraform workspace select dev
terraform apply -var-file="dev.tfvars"
terraform workspace select prod
terraform apply -var-file="prod.tfvars"
|
最佳實務
1. 命名規範
為 workspace 建立一致的命名規範,便於識別和管理:
1
2
3
4
5
6
7
8
9
| # 建議的命名方式
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod
# 或加上專案前綴
terraform workspace new myapp-dev
terraform workspace new myapp-staging
terraform workspace new myapp-prod
|
2. 狀態管理
使用遠端後端(Remote Backend)來儲存狀態,確保團隊協作時的狀態一致性:
1
2
3
4
5
6
7
8
9
10
| # backend.tf
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "project/terraform.tfstate"
region = "ap-northeast-1"
encrypt = true
dynamodb_table = "terraform-lock"
}
}
|
使用 S3 後端時,不同 workspace 的狀態會自動存放在不同的路徑下:
1
2
3
4
| s3://my-terraform-state/
├── env:/dev/project/terraform.tfstate
├── env:/staging/project/terraform.tfstate
└── env:/prod/project/terraform.tfstate
|
3. 環境隔離策略
根據專案需求選擇適合的隔離策略:
| 策略 | 適用場景 | 優點 | 缺點 |
|---|
| 單一 Workspace | 小型專案、單一環境 | 簡單直接 | 無法管理多環境 |
| 多 Workspace | 中型專案、環境配置相似 | 配置共用、易於維護 | 環境差異大時不適用 |
| 多目錄 | 大型專案、環境差異大 | 完全隔離、彈性高 | 配置重複、維護成本高 |
4. CI/CD 整合
在 CI/CD 流程中整合 workspace 操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| # GitLab CI 範例
stages:
- plan
- apply
variables:
TF_WORKSPACE: ${CI_ENVIRONMENT_NAME}
plan:
stage: plan
script:
- terraform init
- terraform workspace select ${TF_WORKSPACE} || terraform workspace new ${TF_WORKSPACE}
- terraform plan -var-file="${TF_WORKSPACE}.tfvars" -out=tfplan
artifacts:
paths:
- tfplan
apply:
stage: apply
script:
- terraform init
- terraform workspace select ${TF_WORKSPACE}
- terraform apply tfplan
when: manual
only:
- main
|
5. 安全注意事項
- 避免在 workspace 名稱中包含敏感資訊
- 確保正式環境的狀態檔案有適當的存取控制
- 使用
terraform plan 確認變更內容後再執行 apply - 對正式環境的操作加入審核流程
1
2
3
4
5
6
7
8
| # 防止意外刪除正式環境資源
resource "aws_instance" "web" {
# ... 其他配置
lifecycle {
prevent_destroy = terraform.workspace == "prod" ? true : false
}
}
|
總結
Terraform Workspace 是管理多環境基礎設施的強大工具。透過適當的規劃和最佳實務,你可以:
- 簡化配置管理:使用單一配置管理多個環境
- 降低維護成本:避免重複的配置檔案
- 提高部署效率:快速切換和部署不同環境
- 確保環境一致性:所有環境使用相同的基礎配置
選擇適合你專案的環境管理策略,並結合 CI/CD 流程,將能大幅提升基礎設施管理的效率和可靠性。