本文為系列文章《跟著 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。
此系列文清單:
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(一)
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(二)
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(三)
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(四)
結構
善用 include:
在上一篇文章,雖然我們只是快速的解釋 Auto-DevOps.gitlab-ci.yml
的內容,但其實也有稍微點出官方是怎麼管理 Pipeline 與 Template,就讓我們先複習上一篇文章是怎麼寫的吧。
善用
include:
管理複雜的 CI/CD Pipeline。include:
允許巢狀結構,因此可以運用分層結構來規劃 Pipeline,例如.gitlab-ci.yml
includepipeline.yml
,pipeline.yml
includestage.yml
,stage.yml
includejob.yml
沒錯,關鍵就是善用 include:
。透過 include:
讓我們可以實現依據不同的層級,定義不同的 .yml
,藉此方便我們規劃與管理 Pipeline,接著就讓我們看看 Auto DevOps 是怎麼處理這件事。
從圖片中我們可以看到,在 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:
之外,所有會「共用」的內容也可以一併定義於此,包含:
- 整個 Pipeline 共用的
Variables
- Pipeline 包含哪些 Stage
- 以
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!