走到第 26 天,Terraform 的篇章也來到尾聲。
在這幾天的內容中,我們看過模組化、provider、資源層級管理,理解了 IaC(Infrastructure as Code)的宣告式精神。
然而,當專案逐漸擴張,我們會發現——問題不在語法,而在「參數」。
幾乎每個平台都能管理設定:
Terraform 有 variable、Helm 有 values.yaml、GitLab 有 CI variable、Kubernetes 還有 ConfigMap、Secret。
這些層級在不同階段各自負責一部分設定,但邊界模糊、重疊頻繁。
因此,今天想談的主題,不是 Terraform 本身,而是參數在多層系統中的治理邏輯與責任邊界。
在 Terraform 的語意中,variable
只是抽象化的起點。
它讓基礎建設能夠「可組態」、可重複部署,但當系統進入多環境、多服務狀態,參數不再只是變數,而是「決策」。
讓我們快速對照三個層級的參數職責:
層級 | 工具 | 職責重點 | 備註 |
---|---|---|---|
Infra 層 | Terraform | 控制雲端資源生命週期、憑證與環境設定 | 參數影響架構與權限 |
Service 層 | Helm Chart | 定義應用啟動行為、Port、Replica、Image tag 等 | 與部署策略緊密相關 |
Pipeline 層 | GitLab CI | 控制部署流程、動態環境、機密注入 | 決策層參數,非執行層 |
從這張表可以看出:
三者的邊界若不清楚,就容易出現「環境參數漂流」:
同一組設定同時存在於 Terraform、Helm、GitLab,各自維護、各自演進,最終導致版本分歧與一致性崩解。
基於這樣的考量,我們在設計 GitLab 專案時,更需要審慎思考:
是以「資源類型」為核心進行專案拆分,還是以「使用情境」作為邏輯邊界?
我們是希望元件能分散、強調重用與彈性,還是讓它們整合於單一專案中,以統一管理、確保一致?
這不僅是專案結構的選擇,更是「參數治理模型」的抉擇。
如前一章所述,在設計 GitLab 專案時,我們需要審慎思考以下問題:
以下將針對不同需求的設計方式做說明。
在大型組織中,我們通常會將 Terraform 與 GitLab CI 各自集中管理:
這種方式能確保資源統一與流程可控,同時各專案保有必要的彈性。
department repo/
├─ terraform/ # 集中管理所有 infra
│ ├─ modules/
│ └─ envs/
├─ gitlab-ci/ # 集中管理 CI/CD 模板與權限
│ └─ templates/
├─ projectA/ # 個別開發專案 A
│ ├─ src/
│ ├─ Dockerfile
│ └─ helm-values/
├─ projectB/ # 個別開發專案 B
│ ├─ src/
│ ├─ Dockerfile
│ └─ helm-values/
└─ projectC/ # 個別開發專案 C
├─ src/
├─ Dockerfile
└─ helm-values/
這樣的架構清楚劃分責任:Terraform 與 CI 集中管理,開發專案專注自身內容。
以環境(dev/stage/prod)或服務/產品線為單位拆分 repo,該 repo 負責該範圍內的 infra 與 app 部署。適合小型團隊,需要快速建置環境。
少數團隊擁有全責任,需快速 rollout,且 service 與 infra 密切耦合。
team-a-prod/ (repo)
├─ terraform/ # 環境小型 infra
├─ helm-charts/
└─ .gitlab-ci.yml # build → terraform plan/app → helm upgrade
team-a-dev/ (repo)
└─ 同上
大多數變數集中在 service/environment repo(方便 local 調整),共享模組仍可從公共 module registry 拉取。
Pipeline 一條龍:build image → terraform plan/app → helm upgrade
可運用 GitLab Environments + Review Apps 進行迭代測試。
對於職責明確、重視長期穩定與維運的團隊,我們會進一步深化任務導向設計,將服務平台化。
例如:
整個平台(infra modules、Helm charts、CI templates、Operator manifests)放入 mono repo。
小型團隊、需要強一致性、方便一次性修改多個部份。
platform-monorepo/
├─ terraform/
│ ├─ modules/
│ └─ envs/
├─ charts/
│ ├─ kafka/
│ └─ flink/
├─ ci-templates/
└─ docs/
由平台擁有者集中管理,透過分支與 Merge Request 控管變更。
MR → CI 執行 unit tests / Terraform validate / Helm lint
protected branch → 觸發 apply。
在釐清專案架構後,下一步需要關注 參數的引入時機與方式。不同層級的參數注入方式決定了專案的彈性、維護成本與跨服務一致性。
常見注入層面包括:
*.tfvars
或 CLI -var
注入,控制基礎設施資源。values.yaml
或 --set
指令注入,用於 Kubernetes 應用部署。參數管理的核心議題:
在 CI/CD 中,明確命名可提升可讀性與維護性。例如:
# .gitlab-ci.yml
include:
- project: 'ci-templates'
file: 'rule.gitlab-ci.yml' # 明確表達用途為 "規則",非一般環境變數
相比使用 env.yml
,rule.gitlab-ci.yml
更直觀,提示團隊這是 代碼風格或 pipeline 規則,而非環境參數,降低混淆風險。
在 Terraform 中,backend 配置與其他環境參數可以透過 config 檔或 GitLab CI 變數集中管理,而不是分散在多個專案中。這樣做的好處是:
# dev-config.tfvars
region = "asia-east1"
project = "projectA"
bucket = "gcs-dev-state"
prefix = "projectA"
env = "dev"
CI pipeline 可直接引用此 config 檔:
# .gitlab-ci.yml 範例
terraform-plan:
stage: plan
script:
- terraform init -backend-config=dev-config.tfvars
- terraform plan -var-file=dev-config.tfvars
variables:
TF_VAR_region: "asia-east1"
TF_VAR_project: "projectA"
TF_VAR_bucket: "gcs-dev-state"
TF_VAR_prefix: "projectA"
TF_VAR_env: "dev"
terraform init -backend-config="bucket=$TF_VAR_bucket" -backend-config="prefix=$TF_VAR_prefix"
terraform plan
在小團隊或單一服務專案中,過度使用 global
層級增加複雜度,維護成本高:
replicaCount: 3
resources:
limits:
cpu: "500m"
memory: "512Mi"
service:
name: nginx
port: 8080
global:
env: dev
route-config: "vpc-eastasia-route-config" # 不必要的抽象
教學重點:對小團隊來說,
global
層級是過度設計,直接拉到最上層更簡單易維護。
env: dev
routeConfig: "vpc-eastasia-route-config" # 直接放最上層,簡化管理
replicaCount: 3
resources:
limits:
cpu: "500m"
memory: "512Mi"
service:
name: nginx
port: 8080
variables:
ENV: "dev"
ROUTE_CONFIG: "vpc-eastasia-route-config"
# 部署 nginx-a
helm upgrade nginx-a ./charts/nginx \
--namespace $ENV \
--set env=$ENV \
--set routeConfig=$ROUTE_CONFIG
# 部署 nginx-b
helm upgrade nginx-b ./charts/nginx \
--namespace $ENV \
--set env=$ENV \
--set routeConfig=$ROUTE_CONFIG
今天我們從 參數治理與專案架構 的角度,梳理了 Terraform、Helm 與 GitLab CI 的角色與邊界,重點整理如下:
IaC 的核心精神不在語法,而在參數管理
專案架構決定參數治理策略
參數引入時機與方式
.tfvars
或 CLI -var
注入,控制基礎設施配置。values.yaml
或 --set
注入,控制應用層行為。在 Terraform 系列的第四天,也是最後一天,我們不僅將 Terraform 放入整體 pipeline 架構中重新審視參數設計,也回顧了系列文中使用的技術,例如 Helm Chart 與 GitLab CI。在理解參數設計的過程中,我們更加清楚地體會到工程實務中的一個世紀難題——命名管理的複雜性,以及抽象與具體落地之間的權衡。
這也呼應了我們系列文章的主題:從抽象到實戰的落地。抽象是一種概念的萃取,它提供視野與可重用模式;而具體落地則驗證了設計的可行性與價值。掌握這種交錯的思維,正是 DevOps 工程設計的重要一環。
希望今天的分享能為各位帶來啟發,也為日後的專案設計與參數治理提供參考。
謝謝各位閱讀,我們明天見!