熱門分類
載入中…
目錄0%

🤖 GitLab CI/CD 最佳實踐:安全掃描、變數管理、Deploy Token 與模組化 Pipelines

    🤖 GitLab CI/CD 最佳實踐:安全掃描、變數管理、Deploy Token 與模組化 Pipelines

    GitLab CI/CD 幾乎是現代 DevOps 團隊的標配:從 Commit 開始自動進行建置、測試、部署與安全掃描,讓版本品質與發佈節奏都更穩定。 本篇整理實務上最常用、也最容易踩雷的部分:環境變數與密鑰管理、Deploy Token 使用方式、 內建安全掃描啟用、以及如何把 Pipeline 拆成模組化結構,讓專案越長越大也不會變成 YAML 地獄。

    📌 一、GitLab CI/CD 核心架構概念

    先快速用幾個關鍵字釐清 GitLab CI/CD 的核心組件:

    • Runner:真正執行 Job 的實體/VM/Container,可以是 Shared Runner 或專案自建。
    • Pipeline:由多個 Stage 與 Job 組成的一次完整流程,例如 build → test → deploy。
    • .gitlab-ci.yml:放在 Repo 根目錄的 YAML 設定檔,描述 Pipeline 規則。
    • Environment:部署目的地,例如 dev、test、stage、prod 等。

    一個最簡單的 Pipeline 可能長這樣:

    stages:
      - build
      - test
      - deploy
    
    build_job:
      stage: build
      script:
        - echo "Building..."
    
    test_job:
      stage: test
      script:
        - echo "Running tests..."
    
    deploy_job:
      stage: deploy
      script:
        - echo "Deploying to production..."
    

    只要把這個檔案命名為 .gitlab-ci.yml 並推上 GitLab,下一次 push 就會自動觸發 Pipeline。

    📌 二、GitLab 內建安全掃描:SAST / DAST / Secret Detection

    在企業與政府專案中,CI/CD 不只是「自動 build & deploy」,同時也扮演「安全守門員」: 每次 Commit 都順便跑一輪安全檢查,可以在正式上線前就抓出潛在問題。

    掃描類型 主要用途
    SAST(Static Application Security Testing) 直接分析原始碼,找出 SQL Injection、XSS 等常見漏洞模式。
    DAST(Dynamic Application Security Testing) 在應用程式實際跑起來時,以黑箱方式模擬攻擊。
    Secret Detection 檢查是否不小心把 API Key、Token、密碼 commit 到 Repo。

    在 GitLab 中啟用其實非常簡單,只要在 .gitlab-ci.yml 中加入官方 Template:

    include:
      - template: Security/SAST.gitlab-ci.yml
      - template: Security/DAST.gitlab-ci.yml
      - template: Security/Secret-Detection.gitlab-ci.yml
    

    加入後的效果:

    • 每次 Pipeline 會自動跑對應掃描。
    • 結果會顯示在 Merge Request 的「Security」或「Pipelines」頁籤。
    • 可以產出報表,方便資安與稽核檢視。

    📌 三、CI/CD 變數管理:密鑰、安全與分層配置

    任何一條像樣的 Pipeline 一定會接觸到各式各樣的機密資訊:

    • Docker Registry 的帳號密碼或 Token
    • 各環境的 API Key、DB 密碼
    • 第三方服務(Cloud、監控系統、Webhook)的憑證

    這些絕對不能硬寫在 .gitlab-ci.yml 裡面,而是要放在 GitLab 的 CI/CD Variables 中。

    1️⃣ Variables 層級與屬性

    層級/屬性 說明
    Group-level Variable 整個群組底下所有 Repo 都共用,例如公司統一的 Registry URL。
    Project-level Variable 只在單一專案內使用,例如該系統專用的 API Key。
    Protected 僅能在 Protected Branch / Tag(如 main、release)使用,避免在測試分支被濫用。
    Masked 即使在 Job Log 中 echo 出來也不會顯示真正的值,可降低洩漏風險。

    設定位置:Project → Settings → CI/CD → Variables

    例如定義一個供 Pipeline 使用的 Token:

    MY_PRIVATE_TOKEN = xxxxxxx(同時勾選 Protected + Masked)
    

    .gitlab-ci.yml 使用方式如下:

    deploy_job:
      stage: deploy
      script:
        - echo "Deploy with token (不會顯示真正內容)"
        - curl -H "Authorization: Bearer $MY_PRIVATE_TOKEN" https://api.example.com/deploy
    

    📌 四、Deploy Token 與 Deploy Key:差異與實務建議

    很多團隊會疑惑:「我要讓外部系統拉 Repo 或拉 Container,要用 Deploy Key?還是 Deploy Token?」, 兩者都可以「給系統存取 Repo」,但設計目標與安全模型完全不同。

    項目 Deploy Token Deploy Key
    型態 帳號+密碼形式,可存取 Repo / Registry SSH 公鑰/私鑰配對,通常用於 Read-only Clone
    常見用途 Kubernetes、外部服務拉 Docker Image CI Job 或外部主機 clone Repo
    安全控制 可設定過期日與權限範圍 常被多專案共用,管理不當較容易留下後門
    建議 正式環境部署強烈建議使用 適合單純 Read-only 使用情境

    正式環境(prod)最佳實務:

    • 使用 Deploy Token 搭配限定權限(僅 Pull Image / Read Repo)。
    • 設定明確過期日,例如 30~90 天,定期汰換。
    • Deploy Token 只給 CI / K8s / 部署系統使用,不給人類開發者日常使用。

    📌 五、Pipeline 模組化設計:避免 YAML 地獄

    專案一開始只有兩三個 Job,還可以靠一個 .gitlab-ci.yml 撐住; 但當你開始拆成多個微服務、支援多個部署環境、又加上一堆掃描與測試, YAML 檔可能很快就破千行,維護成本爆炸。

    建議做法是把 Pipeline 拆成「模組化檔案」,目錄結構可以像這樣:

    .gitlab-ci.yml
    ci-build.yml
    ci-test.yml
    ci-deploy.yml
    ci-security.yml
    

    主檔 .gitlab-ci.yml 負責把所有模組 include 進來:

    include:
      - local: "ci-build.yml"
      - local: "ci-test.yml"
      - local: "ci-deploy.yml"
      - local: "ci-security.yml"
    

    例如 ci-build.yml 可以專心描述 build 相關 Job:

    stages:
      - build
    
    build_app:
      stage: build
      script:
        - npm ci
        - npm run build
      artifacts:
        paths:
          - dist/
    

    好處:

    • 不同小組可以各自維護自己的 CI 模組檔。
    • 同一個 build/test/deploy 模組可以被多個專案共用。
    • 主檔 .gitlab-ci.yml 變成「總目錄」,可讀性更高。

    📌 六、多環境部署範例:dev / test / stage / prod

    在實務中,最常見的環境分層大致如下:

    環境 用途
    dev 開發人員日常測試,允許較高頻率部署。
    test / qa 測試團隊進行功能與回歸測試。
    stage / pre-prod 幾乎等同正式環境,用來做最後驗證。
    prod 正式對外服務,所有操作必須可追蹤、可稽核。

    以下是一個簡化版的多環境部署 YAML 範例:

    stages:
      - build
      - test
      - deploy
    
    build_app:
      stage: build
      script:
        - npm ci
        - npm run build
      artifacts:
        paths:
          - dist/
    
    test_app:
      stage: test
      script:
        - npm test
    
    deploy_dev:
      stage: deploy
      environment:
        name: dev
        url: https://dev.example.com
      script:
        - ./deploy.sh dev
      only:
        - branches
      except:
        - main
    
    deploy_prod:
      stage: deploy
      environment:
        name: production
        url: https://www.example.com
      script:
        - ./deploy.sh prod
      when: manual
      only:
        - main
    

    這裡有幾個重點:

    • dev 環境:對所有分支開放,自動部署,方便開發人員快速驗證。
    • prod 環境:只有 main 分支可以部署,且必須由人手動按下「Play」。
    • Environment 區塊:可搭配 GitLab 的 Environment Dashboard 顯示每個環境目前跑的是哪一個 Commit。

    📌 七、效能最佳化:Cache、Artifacts 與 Runner 策略

    當專案變大、Pipeline 次數變多,CI/CD 速度就會成為開發效率的關鍵。以下是幾個常見的最佳化技巧:

    1️⃣ 善用 Cache 減少重複下載依賴

    cache:
      key: "node-modules"
      paths:
        - node_modules/
    

    搭配 npm ciyarn install,可以大幅減少每次 Pipeline 的依賴下載時間。

    2️⃣ 使用 Artifacts 傳遞建置結果

    不要在每個 Stage 重新 build,而是把 build 出來的結果傳遞給後續 Job 使用:

    build_app:
      stage: build
      script:
        - npm ci
        - npm run build
      artifacts:
        paths:
          - dist/
    
    deploy_prod:
      stage: deploy
      dependencies:
        - build_app
      script:
        - ./deploy_dist.sh
    

    3️⃣ Runner 規劃建議

    • 針對不同任務類型使用不同 Tag(例如 dockershell)。
    • 怕影響正式環境的部署 Job,請使用專屬 Runner,不與一般 build/test 共用。
    • 有大量 parallel job 時,可用 autoscaling Runner(例如搭配 K8s 或 Cloud)動態擴縮。

    📌 八、實務安全建議總整理

    最後整理一份「CI/CD 安全 Checklist」,方便在導入或稽核時快速檢查:

    • 所有 Token、密碼都放在 CI/CD Variables,不寫死在 YAML 或程式碼。
    • 重要變數一律設為 Protected + Masked
    • Production 部署 Job 一律設定 when: manual,並只允許 main / release 分支觸發。
    • Deploy Token 設定過期日與必要最小權限(Principle of Least Privilege)。
    • 啟用 SAST / DAST / Secret Detection 等安全掃描。
    • 限制 Runner Tag,避免不可信的 Job 在敏感 Runner 上執行。
    • 設定 Branch Protection 規則:要求 Merge Request、至少一位 reviewer 通過才能合併。

    🔗 延伸閱讀

    — WWFandy・DevOps 自動化工程筆記

    🔗 分享這篇 LINE Facebook X

    沒有留言:

    字級