iT邦幫忙

2025 iThome 鐵人賽

DAY 3
0
自我挑戰組

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

Day3 從工程案例看「抽象」的實用價值

  • 分享至 

  • xImage
  •  

在工程世界裡,抽象不是哲學上的空談,而是日常中無處不在的工具。它就像一層「隱形的結構」,幫助我們面對複雜的系統時,仍能保持清晰的操作與判斷。今天,我想透過幾個實際案例,來說明抽象如何在工程實務裡發揮價值。

案例一:Helm values.yaml 的抽象

Helm Chart 提供了 values.yaml 作為「使用者介面」。對開發者而言,它隱藏了繁雜的 Kubernetes manifest 細節,讓我們只需要修改少量的參數,就能完成部署。

沒有抽象時,你可能需要在 Deployment 裡修改許多地方,例如調整 image、資源限制或環境變數,這樣的操作不僅容易出錯,也難以維護:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kafka
spec:
  template:
    spec:
      containers:
        - name: kafka
          image: kafka:0.47.0-kafka-3.9.0
          env:
            - name: ENV
              value: "staging"
          resources:
            limits:
              cpu: "4"
              memory: 16Gi
            requests:
              cpu: 250m
              memory: 2Gi

抽象後,我們只需調整 values.yaml 裡的幾個簡單參數,整個部署行為就能跟著更新,語意更直接、簡潔:

kafka:
  image: kafka:0.47.0-kafka-3.9.0
  limit: cpu-4,mem-16G
  requests: cpu-250,mem-2G

這種方式讓配置更直覺,降低因人工作業導致錯誤的風險。當我們把多層次的細節收斂為一個清晰的結構時,保留了靈活性,同時維持了一致性,讓複雜度不至於無限制膨脹。


案例二:Terraform Module 的抽象

Terraform 的 module 本身就是一種抽象實作,能將複雜的資源設定封裝起來,讓基礎架構能夠重複利用。更進一步的做法,是使用 locals 定義變數,再搭配 YAML 作為外部輸入,讓 Terraform 程式碼與環境配置分離,實現更高的可讀性與維護性。

最初版本是直接撰寫資源,每個細節都必須逐一描述,雖然清楚,但重複度高、修改麻煩:

resource "google_storage_bucket" "raw" {
  name          = "my-raw-data"
  location      = "ASIA"
  force_destroy = true
  versioning { 
    enabled = true
  } 
  lifecycle_rule {
    action { 
      type = "Delete" 
    } 
    condition { 
      age = 30 
    }
  }
}

當我們將邏輯封裝進 module 之後,呼叫就變得簡單許多,只需傳入必要參數,所有細節都隱藏在 module 內:

module "gcs_bucket" {
  source   = "./modules/gcs"
  name     = "my-raw-data"
  region   = "ASIA"
  logs     = true
  lifecycle_days = 30
}

如果再進一步抽象,讓 Terraform 只解析 YAML 檔案,維護起來就更加清晰,且更適合大型專案:

buckets:
  my-raw-data:
    region: "ASIA"
    lifecycle_days: 30

這樣的分層設計,讓工程師不用頻繁修改 Terraform 程式碼,只需專注在 YAML 檔案中定義需求即可。抽象在這裡扮演的是「隔離細節」的角色,幫助團隊降低心智負擔,並確保設定可以持續擴展。從一開始直接寫資源,到使用 module,再到 YAML 配置,層層抽象讓基礎架構管理變得更加高效,並且降低了錯誤發生的機會。


案例三:GitLab CI 的抽象取捨 — 明確來源 vs 通用設計

抽象在很多時候是需要取捨及平衡的。以 GitLab CI 為例,我們在設計 pipeline 時,必須在「明確性」與「通用性」之間找到平衡。

第一種寫法是將所有參數明確列出,像是將服務設定一一標示清楚:

variables:
  TF_ROOT: prod/terraform
  TF_Backend: "prod.config"
  TF_CLI_ARGS_plan: "-var env_yml=prod"

terraform-plan:
  stage: build
  image:
    name: hashicorp/terraform:1.9.1
    entrypoint: [""]
  script:
    - cd $TF_ROOT
    - terraform init --backend-config=$TF_Backend
    - terraform plan -out plan.tfplan
    - terraform show -json plan.tfplan > plan.json

這樣的優點是透明易讀,每個變數都清楚呈現,像是「所見即所得」。但當專案規模擴大、環境增多時,這種明確的寫法會迅速膨脹,設定檔變得冗長且難以維護。

第二種寫法則對通用性參數進行抽象,減少了對於stage所作行為的關心,將管理聚焦在參數的注入:

variables:
  ENV: prod

terraform-plan:
  stage: build
  image:
    name: hashicorp/terraform:1.9.1
    entrypoint: [""]
  script:
    - cd $ENV/terraform
    - export TF_VAR_env=$ENV
    - terraform init --backend-config=$ENV.config

這樣的方式更加簡潔,也能適應多環境專案,因為只需改動一個變數即可。然而,對新進成員來說,這種隱藏邏輯的抽象會降低直覺理解的便利性。從抽象的角度看,它將共通模式提取出來,降低重複操作的負擔。但也可能增加新成員的學習成本。

從這個案例可以看出,抽象的目的會深刻影響設計,而在設計過程中,必須平衡簡潔、效率與可讀性。除了保持配置的簡潔與高效外,也需要考量團隊成員的理解成本以及後期維護成本。工程師應依據專案規模、使用者熟悉度以及維護需求,判斷哪些部分適合抽象,哪些部分應保留明確性,才能同時達到最佳的工程效能與可維護性。


結語:抽象的價值,在於更好的工程體驗

從這個章節可以看到,抽象設計在 DevOps 工程中具有許多值得深思的環節。除了模組化帶來的重用性,以及共通性萃取的便利,抽象的核心目的始終不離「服務使用者」。儘管 DevOps 工程不像程式開發有明確的邏輯堆疊(程式中的抽象更多為模組化與通用性),也不同於前端設計的「所見即所得」,但 DevOps 工程師仍能遵循相同的開發典範:將設定檔視為使用者介面,將參數設計成模組,藉此達成更高效率的管理。

抽象讓工程師專注於「我要什麼」,而非「該怎麼實作」,同時兼顧可讀性與維護性。正如抽象與具體之間的衡量,需要工程師在實務中判斷與設計,這也是我希望在這一系列文章中探討的核心:如何透過抽象提升工程體驗,讓系統既簡潔、高效,又貼近使用者的需求。


上一篇
Day2 抽象的兩種面貌:中文語境的誤解與外文語境的價值
下一篇
Day4 過度抽象 vs 過度具體:設計的平衡點
系列文
雲端與資料平台實戰:從抽象概念到落地技術9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言