iT邦幫忙

2025 iThome 鐵人賽

DAY 26
0
自我挑戰組

雲端與資料平台實戰:從抽象概念到落地技術系列 第 26

Day26 參數的邊界:Terraform、GitLab、Helm 的治理平衡

  • 分享至 

  • xImage
  •  

走到第 26 天,Terraform 的篇章也來到尾聲。
在這幾天的內容中,我們看過模組化、provider、資源層級管理,理解了 IaC(Infrastructure as Code)的宣告式精神。
然而,當專案逐漸擴張,我們會發現——問題不在語法,而在「參數」。

幾乎每個平台都能管理設定:
Terraform 有 variable、Helm 有 values.yaml、GitLab 有 CI variable、Kubernetes 還有 ConfigMap、Secret。
這些層級在不同階段各自負責一部分設定,但邊界模糊、重疊頻繁。
因此,今天想談的主題,不是 Terraform 本身,而是參數在多層系統中的治理邏輯與責任邊界


回顧與盤點:從 IaC 看參數責任

在 Terraform 的語意中,variable 只是抽象化的起點。
它讓基礎建設能夠「可組態」、可重複部署,但當系統進入多環境、多服務狀態,參數不再只是變數,而是「決策」。

讓我們快速對照三個層級的參數職責:

層級 工具 職責重點 備註
Infra 層 Terraform 控制雲端資源生命週期、憑證與環境設定 參數影響架構與權限
Service 層 Helm Chart 定義應用啟動行為、Port、Replica、Image tag 等 與部署策略緊密相關
Pipeline 層 GitLab CI 控制部署流程、動態環境、機密注入 決策層參數,非執行層

從這張表可以看出:

  • Terraform 建構基礎資源與外部依賴
  • Helm 管理應用層的配置與運作方式
  • GitLab 負責協調流程,決定何時、以何種條件部署

三者的邊界若不清楚,就容易出現「環境參數漂流」:
同一組設定同時存在於 Terraform、Helm、GitLab,各自維護、各自演進,最終導致版本分歧與一致性崩解。

基於這樣的考量,我們在設計 GitLab 專案時,更需要審慎思考:
是以「資源類型」為核心進行專案拆分,還是以「使用情境」作為邏輯邊界?
我們是希望元件能分散、強調重用與彈性,還是讓它們整合於單一專案中,以統一管理、確保一致?

這不僅是專案結構的選擇,更是「參數治理模型」的抉擇。


專案設計與架構考量

如前一章所述,在設計 GitLab 專案時,我們需要審慎思考以下問題:

  • 專案拆分是以「資源類型」為核心,還是以「使用情境」作為邏輯邊界?
  • 我們希望元件能分散、強調重用與彈性,還是希望它們整合於單一專案中,以統一管理、確保一致性?

以下將針對不同需求的設計方式做說明。


1️⃣ 資源導向:統一管理(大型組織常用)

在大型組織中,我們通常會將 Terraform 與 GitLab CI 各自集中管理

  • Terraform 專案:集中管理所有基礎建設資源,統一模組與環境設定。
  • GitLab CI 專案:統一管理 CI/CD 流程與權限(如部署 token),提供各開發專案引用。
  • 個別開發專案:僅保留該專案程式碼、Dockerfile、Helm values 等開發內容。

這種方式能確保資源統一與流程可控,同時各專案保有必要的彈性。

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 集中管理,開發專案專注自身內容。


2️⃣ 任務/使用情境導向(Environment / Service-oriented)

說明

以環境(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 拉取。

CI 流程

Pipeline 一條龍:build image → terraform plan/app → helm upgrade
可運用 GitLab Environments + Review Apps 進行迭代測試。

優缺點

  • 優:快速建立環境,infra 與 app 盡在同一處。
  • 缺:重複性高、跨團隊重用困難,管理多個相似 infra 易失控。

3️⃣ 平台化設計(強一致性與長期維運)

對於職責明確、重視長期穩定與維運的團隊,我們會進一步深化任務導向設計,將服務平台化。

例如:

  • Helm 部署需指定資源、node label、taint/affinity,同一份 YAML 被 Terraform 讀取以建立資源。
  • 資料流建構從 source DB 到資料倉儲的同步,可設計通用 YAML 適用於 source、sink 與資料倉儲 dataset。

說明

整個平台(infra modules、Helm charts、CI templates、Operator manifests)放入 mono repo。

適用場景

小型團隊、需要強一致性、方便一次性修改多個部份。

platform-monorepo/
├─ terraform/
│  ├─ modules/
│  └─ envs/
├─ charts/
│  ├─ kafka/
│  └─ flink/
├─ ci-templates/
└─ docs/

參數擁有權

由平台擁有者集中管理,透過分支與 Merge Request 控管變更。

CI 流程

MR → CI 執行 unit tests / Terraform validate / Helm lint
protected branch → 觸發 apply。

優缺點

  • 優:易管理、可一次修改多個層面、學習曲線平坦。
  • 缺:隨規模擴張可能成為巨型 repo,權限劃分與部署速度可能受影響。

參數管理與引入時機的設計思考

在釐清專案架構後,下一步需要關注 參數的引入時機與方式。不同層級的參數注入方式決定了專案的彈性、維護成本與跨服務一致性。

常見注入層面包括:

  1. Terraform:透過 *.tfvars 或 CLI -var 注入,控制基礎設施資源。
  2. Helm:透過 values.yaml--set 指令注入,用於 Kubernetes 應用部署。
  3. GitLab CI:透過 pipeline 變數注入,控制 build、deploy 流程或跨專案共用設定。

參數管理的核心議題

  • 專案範圍:參數僅限於單一專案,例如 projectA 的 Terraform 與 Helm 部署。
  • 跨服務範圍:共享模組或多專案共用資源,需要統一命名、標準化管理,以避免衝突或混淆。

1️⃣ GitLab CI 範例:明確命名提高可維護性

在 CI/CD 中,明確命名可提升可讀性與維護性。例如:

# .gitlab-ci.yml
include:
  - project: 'ci-templates'
    file: 'rule.gitlab-ci.yml'   # 明確表達用途為 "規則",非一般環境變數

相比使用 env.ymlrule.gitlab-ci.yml 更直觀,提示團隊這是 代碼風格或 pipeline 規則,而非環境參數,降低混淆風險。


2️⃣ Terraform 範例:參數封裝與 CI 注入

在 Terraform 中,backend 配置與其他環境參數可以透過 config 檔或 GitLab CI 變數集中管理,而不是分散在多個專案中。這樣做的好處是:

  • 參數在 CI YAML 層級清晰可見,便於審核與維護。
  • 避免不同專案或開發者在各自環境中硬編碼,降低錯誤風險。
  • 支援跨專案統一管理 backend、環境變數或模組參數。

封裝成 config 檔(範例)

# 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

或使用 GitLab CI 變數集中注入

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

3️⃣ Helm 範例:單專案與跨服務設計

3-1. 小團隊單專案設計(反面教材)

在小團隊或單一服務專案中,過度使用 global 層級增加複雜度,維護成本高:

replicaCount: 3
resources:
  limits:
    cpu: "500m"
    memory: "512Mi"
service:
  name: nginx
  port: 8080
global:
  env: dev
  route-config: "vpc-eastasia-route-config"   # 不必要的抽象

教學重點:對小團隊來說,global 層級是過度設計,直接拉到最上層更簡單易維護。

3-2. 改進設計:將環境與共用參數放到最上層

env: dev
routeConfig: "vpc-eastasia-route-config"  # 直接放最上層,簡化管理
replicaCount: 3
resources:
  limits:
    cpu: "500m"
    memory: "512Mi"
service:
  name: nginx
  port: 8080

3-3. GitLab CI 變數管理跨服務參數

variables:
  ENV: "dev"
  ROUTE_CONFIG: "vpc-eastasia-route-config"

3-4. CI/CD pipeline 注入 Helm

# 部署 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 的角色與邊界,重點整理如下:

  1. IaC 的核心精神不在語法,而在參數管理

    • Terraform、Helm 與 GitLab CI 都可管理設定,但各自負責的層級與責任不同。
    • 若邊界不明確,容易出現「環境參數漂流」,導致版本分歧與一致性崩解。
  2. 專案架構決定參數治理策略

    • 資源導向(大型組織):Terraform 與 GitLab CI 集中管理,開發專案只保留程式碼與部署參數,強調統一與可控。
    • 任務/使用情境導向(小團隊):以服務或環境拆分 repo,快速 rollout,但跨團隊重用受限。
    • 平台化設計:mono repo 集中管理 infra、Helm、CI templates,適合追求強一致性與長期維運的團隊。
  3. 參數引入時機與方式

    • Terraform:透過 .tfvars 或 CLI -var 注入,控制基礎設施配置。
    • Helm:透過 values.yaml--set 注入,控制應用層行為。
    • GitLab CI:透過 pipeline 變數注入,支援跨專案共用或流程控制。
    • 設計原則:專案範圍與跨服務範圍的參數需清楚區隔,命名一致性與集中管理至關重要。

在 Terraform 系列的第四天,也是最後一天,我們不僅將 Terraform 放入整體 pipeline 架構中重新審視參數設計,也回顧了系列文中使用的技術,例如 Helm Chart 與 GitLab CI。在理解參數設計的過程中,我們更加清楚地體會到工程實務中的一個世紀難題——命名管理的複雜性,以及抽象與具體落地之間的權衡。

這也呼應了我們系列文章的主題:從抽象到實戰的落地。抽象是一種概念的萃取,它提供視野與可重用模式;而具體落地則驗證了設計的可行性與價值。掌握這種交錯的思維,正是 DevOps 工程設計的重要一環。

希望今天的分享能為各位帶來啟發,也為日後的專案設計與參數治理提供參考。

謝謝各位閱讀,我們明天見!


上一篇
Day25 Terraform 的宣告式語言與 HCL 函數運用
下一篇
Day27 技術落地的收束與整合
系列文
雲端與資料平台實戰:從抽象概念到落地技術27
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言