跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(二)

系列文第二篇,本系列文將會逐一檢視並解析 GitLab Auto DevOps 背後的 Templates,讓我們一起跟著 GitLab Auto DevOps 學習 GitLab CI/CD Pipeline。

本文為系列文章《跟著 GitLab Auto DevOps 學習 CI/CD Pipeline》的第二篇,藉由逐一檢視並解析 GitLab Auto DevOps 背後的 Templates,讓我們一起跟著 GitLab Auto DevOps 學習 GitLab CI/CD Pipeline。

上一篇文章,我們了解 Auto DevOps 可說是 GitLab CI 的火力展示,它以 Auto-DevOps.gitlab-ci.yml 為起點,利用 include: 引用了多個 Template,構成了可以自動產生 Pipeline 的 Auto DevOps 功能。本文我們將延續上一篇文章,從 Auto-DevOps.gitlab-ci.yml 繼續認識官方是怎麼規劃與管理 pipeline 與 templates。

此系列文清單:

結構

善用 include:

上一篇文章,雖然我們只是快速的解釋 Auto-DevOps.gitlab-ci.yml 的內容,但其實也有稍微點出官方是怎麼管理 Pipeline 與 Template,就讓我們先複習上一篇文章是怎麼寫的吧。

善用 include: 管理複雜的 CI/CD Pipeline。include: 允許巢狀結構,因此可以運用分層結構來規劃 Pipeline,例如 .gitlab-ci.yml include pipeline.ymlpipeline.yml include stage.ymlstage.yml include job.yml

沒錯,關鍵就是善用 include:。透過 include: 讓我們可以實現依據不同的層級,定義不同的 .yml,藉此方便我們規劃與管理 Pipeline,接著就讓我們看看 Auto DevOps 是怎麼處理這件事。

大量 include 多個 template

從圖片中我們可以看到,在 include: 之下,引用了大量的 Template,並且按照特定的規則來命名。也就是將 CI Job 視為是 Pipeline 的最小單位,將個別的 Job 單獨撰寫成一個又一個的 .yml 作為 Template,同時集中存放在名為 Jobs 的資料夾中,然後依據管理上的需要,將 Security 相關的 Template 特別另外放在 Security 資料夾集中管理。

如果你再繼續深入查看,例如最後一個被 include 的 template - Security/Secret-Detection.gitlab-ci.yml,會發現該檔案的內容又出現 include:,引用了同樣是集中存放於 Jobs 內的另一個 template。

include:
  template: Jobs/Secret-Detection.gitlab-ci.yml

看到這裡,相信大家應該不難理解官方是如何運用 include:,以及這樣做在管理上的好處。

結構

pipeline 的共用內容

延續上面的內容,既然 Auto-DevOps.gitlab-ci.yml 等同於我們放在 Project 內的 .gitlab-ci.yml,即是用來設置 CI/CD Pipeline 的起點,因此除了 include: 之外,所有會「共用」的內容也可以一併定義於此,包含:

  1. 整個 Pipeline 共用的 Variables
  2. Pipeline 包含哪些 Stage
  3. workflow: 定義,在那些條件之下,才需要產生 CI/CD Pipeline

這三項我們在上一篇文章也都概略提過,這裡就不再重複,關於這三點,我們後續會另外撰文深入說明。這裡我只想要再次提醒,由於 .gitlab-ci.yml 是設置 Pipeline 的起點,因此在結構上,可以將整個 Pipeline 共用的內容都定義在此,讓我們以 Variables 為例,這邊要定義的就是「整個 Pipeline 共用的 Variables」,倘若有某個 Variable 只適用於單一的 CI Job,那就應該將它移至該 CI Job 的 Template 中定義。

應用

前面我們認識了官方的結構,接著我們就可以學習它,應用在我們的 Project 中。

首先,在 .gitlab-ci.yml 學習官方作法,先定義 Pipeline 共用的內容,然後 include: 所需的 CI Job。

# 執行 CI Job 的預設 container image
image: alpine:latest

# 所有 CI Job 皆會用到的共用變數
variables:
  ## 例如你有額外串接其他的 container registry,可能每個 CI Job 都要去那邊 pull image。
  CONTAINER_REGISTRY: 

# Pipeline 有哪些 stage
stages:
  - build
  - test
  - deploy

# workflow 我們這邊先跳過不談,留待後續專文介紹
# workflow:

# 最後引用所需的 CI Job 
include:
  - local: '/Jobs/build.yml'
  - local: '/Jobs/unit-test.yml'
  - local: '/Jobs/ui-test.yml'
  - local: '/Jobs/deploy/server.yml'

【補充】template: 只能引用 GitLab Server 上已預備好的 Template,因此如果是 gitlab.com 的使用者,你使用 template: 時,就只能引用官方有公佈的那些。但如果你是自架 GitLab Server,那你可以在 Admin > Settings > Templates 新增更多的 Templates。

在上面的範例中,include: 之下我用的是 local:,這代表我要引用的是存放在同一個 Project 的 .yml。實務上我們可以將這些 CI Job 用另一個 Project 管理,改用 include:project 的方式引用。舉例來說,你可以建立一個 Project 名為 my-pipeline-template,同時採用常見的分支策略管理它,像是使用 main 或 master branch,或打 tag 區別各個 stable 版本。以單獨的 Project 管理後,上述的 include: 就可以修改類似下面這樣。

include: 
  - project: 'my-pipeline-template'
    ref: v2021.1
    file:
      - '/Jobs/build.yml'
      - '/Jobs/unit-test.yml'

  - project: 'my-pipeline-template'
    ref: main
    file:
      - '/Jobs/unit-test.yml'
      - '/Jobs/deploy/server.yml'

透過此種方式,就如上面的範例那樣,你甚至可以搭配版本控制的分支或版號,更彈性的組合出所需的 CI/CD Pipeline,同時也更加強化了讓 Pipeline 能更吻合 as Code 概念的方式來管理與維護。

【補充】透過 include: 的方式來彈性組合出 Pipeline,還有另外一個好處,就是可以減少為了修改 CI/CD Pipeline 而反覆送出與 Application 無關的 Commit。

在最基本的 GitLab CI 使用方式中,我們會在 Project 內新增 .gitlab-ci.yml 然後在其中直接描述所需的所有 CI Job。但在 Project 的初期,你可能才剛開始建構 Pipeline,需要反覆的修改並測試 pipeline,因此經常會出現為了修改 .gitlab-ci.yml 而反覆送出與該 Project 本身無關之 Commit 的狀況。

但在以 include: 引用 Template 組合出 Pipeline 的狀況中,當我們為了修正 CI Job 而修改了 Template 檔案,接著我們只需再次按下 Project > CI/CD > Pipelines 介面上的 Run pipeline 按鈕,讓該 Project 產生一條新的 Pipeline,即能在新 Pipeline 上繼續驗證新修改過的 CI Job。如此一來就能讓 Pipeline 相關的 Commit 歸於 Pipeline 的 Project,免去在 Application 的 Project 中反覆送出無關的 Commit。

至於針對 CI Job Template 的管理,就如前面提到的,我們可以學習官方的做法,視 CI Job 為 Pipeline 的最小單位,將不同的 CI Job 撰寫為獨立的 .yml,並集中於另一個 Project 以資料夾分類管理,例如下面這樣:

# CI Job 分成單獨的檔案,但集中在同一個資料夾內管理
Jobs/build.yml
Jobs/unit-test.yml
Jobs/security-test.yml
Jobs/ui-test.yml
## 如果有必要,可以在 Jobs 內繼續分門別類
Jobs/deploy/server.yml
Jobs/deploy/container.yml
Jobs/deploy/k8s.yml

這樣一來,即便你手上的 CI/CD 情境越來越多元,只要你能夠妥善地將 pipeline 與 CI Job 標準化做成自己的 Template,即可善用 GitLab CI 彈性的管理各 Project 的 CI/CD Pipeline。

結語

最後總結一下本文我們學習了哪些重點:

  • .gitlab-ci.yml 是我們設置 Pipeline 的起點,在其中先定義 Pipeline 共用的內容。
  • 將經過標準化,可供多個 Project 使用的 CI Job 獨立放在同一個 Project 中 ,將它們作為你自己的 CI Job Templates 來管理它們。
  • 在各個 Project 中,透過 include:project 引用你自己的 CI Job Templates,以此彈性的組合出個別 Project 所需的 Pipeline。

最後,再給大家一點延伸思考,除了針對 Pipeline 最小單位的 CI Job 做出 Template,我們還能根據不同層級做出哪些 Template 呢?下面我就隨便舉個例子:(小提示,可以參考一下官方除了 Auto DevOps 之外,還提供了哪些 Templates。)

Jobs/build-c.yml
Jobs/build-go.yml
Jobs/unit-test.yml
Jobs/ui-test.yml

Stages/security.yml
Stages/stg-deploy.yml
Stages/prod-deploy.yml

pipelines/laravel.yml
pipelines/ruby-on-rails.yml

結構

大家也可以思考一下,你會怎麼運用 include: 來規劃與管理 Pipeline 與 Template!

參考資料

轉貼本文時禁止修改,禁止商業使用,並且必須註明來自「艦長,你有事嗎?」原創作者 Cheng Wei Chen,及附上原文連結。

工商服務

更多文章