自從 GitLab 推出 Auto DevOps 功能之後,我在許多演講與社群的場合都曾分享過,其實 Auto DevOps 並不是真的那麼「Auto」,它的背後是仰賴 GitLab 官方事先預備好的眾多 GitLab CI Templates,這些 Templates 能夠根據 Project 內容,自動產生多種情境的 CI/CD Pipeline。因此如果你想要自學 GitLab CI 的各種進階用法與技巧,或想要參考別人如何規劃 CI/CD Pipeline,那麼這些建構出 Auto DevOps 的諸多 CI Templates 即是我們絕佳的學習與參考對象。
既然 GitLab 官方準備了這麼好的學習材料,當然要好好運用它,因此從本文開始,接下來我將以系列文的方式,逐一檢視並解析 GitLab Auto DevOps 背後的 Templates,讓我們一起跟著 GitLab Auto DevOps 學習 GitLab CI/CD Pipeline。
此系列文清單:
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(一)
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(二)
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(三)
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(四)
Auto DevOps CI Templates
首先讓我們快速查看 GitLab 官方準備的 Auto DevOps CI Templates,如下網址,我們可以在官方公開的 GitLab Project 中找到它們。
如上圖,雖然在這裡可以找到所有的 Template,但看著這依據檔名排序的資料夾結構,其實不太方便我們學習,有沒有更吻合 CI/CD Pipeline 脈絡的依據可以讓我們學習呢?答案是當然有,我們可以從 Auto-DevOps.gitlab-ci.yml
作為我們學習的起點。
Auto-DevOps.gitlab-ci.yml
Auto-DevOps.gitlab-ci.yml
是 GitLab Auto DevOps 自動產生 CI/CD Pipeline 的起點,它就是一個標準的 GitLab CI YAML 檔(.gitlab-ci.yml
),其中定義了 Pipeline 的 Stages 以及要引用哪些 CI Templates,下面讓我們逐一瀏覽它有哪些內容:
首先是定義 images:
與 variables:
,給予必要的預設值。這一段我們就先跳過,先不探討這些 variables:
的意義,但可以提一下的是,當我們在規劃自己的 GitLab CI Pipeline 時,可以善用 GitLab CI 對於 Variables 的優先順序,給予 Variables 預設值,並在必要的時候覆蓋它,藉此讓 Pipeline 可以規劃的更靈活。(有機會再另外針對這主題撰文。)
接著是 stages:
,如上圖可以看到官方預先規劃了共 14 個 Stage,其中包含了 CI/CD Pipeline 必備的 2 個 Stage:
- build
- test
這兩個 Stage 應該不用太多的解釋,基本上就是 CI Pipeline 的基本,透過 build
將 Source code 編譯成可運行的 Application 並打包為 Artifacts,如果是不需編譯的程式語言,例如 PHP,在 build
則多半會是下載相依的 Package,最後將所有檔案一併打包為 Artifacts。而 test
則是實行持續整合(CI)的關鍵動作——執行各種自動化測試。
而與部署相關的 Stage 則有多個:
- deploy
- review
- staging
- canary
- production
- incremental rollout 10%
- incremental rollout 25%
- incremental rollout 50%
- incremental rollout 100%
以吻合持續交付(CD)的概念,同一份 Artifacts,透過同一條 Pipeline 可以部署至不同的環境,review
是給像是 feature branch 這一類分支使用的部署。canary
是用來實現金絲雀部署。而 staging
在 Auto DevOps 的概念比較類似 pre-prodcution 環境,而 production
則不用說指的就是部署至 Production 環境。至於那些 incremental rollout
顧名思義即是用來實現 Rolling update 這種從 10% 逐步增量將程式部署至所有主機的部署策略。
從這裡我們可以學習到,為了區別不同環境與部署策略,在規劃 Pipeline 時,可以按照先後順序,以 stages:
來分別安排它們。
【補充】在 GitLab CI 中,CI Job 一定要分配
stage:
,但stages:
裡面不一定要有 CI Job,因此在 Pipeline 初期規劃階段,你其實可以大膽的列出所有想要的stages:
,然後隨著 Pipeline 的逐步改善,將每個 Stage 的 CI Job 慢慢補上。
其中有兩個 Stage 是比較特別一點的測試:
- dast
- performance
dast
是 Dynamic Application Security Testing 的縮寫,這目前是 GitLab 的付費功能,這裡我們也先暫時不深入探討,總之就是面對新型態的攻擊,我們可以在 Pipeline 中塞入更厲害的自動化測試,對於 DAST 先大致認識到此即可。
【補充】GitLab 的 DAST 背後是利用 OWASP Zed Attack Proxy 進行掃描,這是一項開源工具,因此你也可以嘗試自行將它整合在你的 CI/CD Pipeline。
performance
即是 Performance testing,這個 Stage 會安排在 Production 環境部署之後,幫你測試 Production 環境的網站效能。
【補充】Auto DevOps 是使用 sitespeed.io 來進行 Performance testing,因此你同樣也可自行將它整合在你的 CI/CD Pipeline,這部分的內容我過去在 iT 邦幫忙鐵人賽與我的著作《和艦長一起 30 天玩轉 GitLab》中都有分享過。
最後一個是擔當清道夫角色的 Stage:
- cleanup
CI/CD Pipeline 在執行過程中,難免會遇到失敗,但有時失敗的 CI Job 在執行過程中多少已產生了一些檔案,長久下來這些執行到一半的檔案可能會累積起來變成某種「垃圾」,因此我們可以學習 Auto DevOps,在 CI/CD Pipeline 中規劃 cleanup
的 Stage,利用它自動清除這些「垃圾」。至於 cleanup
該如何規劃,我們同樣留待後續的文章再詳細介紹。
接下來是從 Line 86 ~ 161 是一整段的 workflow:
,這邊就是 Auto DevOps 第一個關鍵重頭戲,針對 workflow:
我們先建立一個基本認識,workflow:
類似程式語言中的 if / else
,在 GitLab CI 我們可以利用 workflow:
設置不同的條件,藉此控制 GitLab CI 判斷哪些情境之下,才需要產生 CI/CD Pipeline,在實務上會搭配多種條件來設置。這麼重要的功能,當然要好好寫一篇文章單獨說明,所以本文還是先跳過它不詳談。(喂~)
最後是 Auto DevOps 第二個關鍵重頭戲,利用 include:
引用了多個 Template。如上圖可以看見這邊 Templates 大致上是按照前面 stages:
的排序條列的,而這也正是為何前面我會說 Auto-DevOps.gitlab-ci.yml
能作為我們學習起點的其中一項原因。我們可以按著 stages:
對照每一個 Template 及後方註解的網址,一層一層抽絲剝繭的學習官方是如何規劃每一個 Stage 與 CI Job 的內容,本系列文後續也將依此脈絡逐一解析 Auto DevOps。
【補充】GitLac CI 的
include:
是允許巢狀結構的,也就是說你可以在.gitlab-ci.yml
includeTemplate A
,然後Template A
中又 includeTemplate B
。因此在實務上,我們其實可以這樣運用,在.gitlab-ci.yml
includepipeline.yml
,而pipeline.yml
的內容是定義 CI/CD Pipleine 的基本結構;接著在pipeline.yml
中 includestage-build.yml
,這邊定義 Stage 層級的內容;最後stage-build.yml
中 includejob-build.yml
,將 CI Job 層級的內容定義於此。善用巢狀結構有助於我們管理龐大且複雜的 CI/CD Pipelone。(此系列文後續我們會再詳談這部分的內容。)
結語
本文是「跟著 GitLab Auto DevOps 學習 CI/CD Pipeline」系列文的第一篇,在本文中我們快速認識了 Auto DevOps CI Templates 的起點 Auto-DevOps.gitlab-ci.yml
,這個檔案它就像是整串肉粽的肉粽頭,是整個 Auto DevOps Pipeline 的起點,GitLab 官方由此開始透過 GitLab CI 的 include:
一層又一層的引用多個 CI Templates,最終建構出 Auto DevOps 這個神奇的功能。
最後複習一下本文中我們點到為止的幾個學習:
- 善用 GitLab CI Variables 的優先順序,給予 Variables 預設值,並在適當的地方覆蓋它,讓 Pipeline 有更多變化與彈性。
- GitLab CI 的 CI Job 一定要分配
stage:
,但stages:
裡面不一定要有 CI Job,因此在實務操作上,我們可以先規劃好 Stage,再依據進度逐一補上 CI Job。 - 思考「持續交付」的重要原則,在規劃 CI/CD Pipeline 時,要考慮如何讓同一份 Artifacts 部署至不同的環境。
- 善用
include:
管理複雜的 CI/CD Pipeline。include:
允許巢狀結構,因此可以運用分層結構來規劃 Pipeline,例如.gitlab-ci.yml
includepipeline.yml
,pipeline.yml
includestage.yml
,stage.yml
includejob.yml
參考資料
- https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates
- https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
- https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
- https://docs.gitlab.com/ee/user/application_security/dast/
- https://owasp.org/www-project-zap/