昨天說到了透過pipeline
將kong
設定檔變更後,雖然有諸多優點。但是對於Infratructure
的人通常會覺得麻煩,而且會被挑戰一件事情,那就是當事故發生的當下,要還原會非常麻煩。
這件事情的確是存在的,過去例如網管在設定防火牆時,不小心設定錯誤,事件發生當下,只要能確認錯誤所在,其實一兩個按鈕就可以還原回去了。大師級的網管或許只需要10秒鐘,就可以將災難還原。
但是,別忘了。那是在變更管理後已經鎖定錯誤所在,才會能夠真的快速還原事故狀態。但通常每一位專業人士獨立作業時,只要該同仁暫時離開了座位上(或許去便利商店買咖啡排隊排很久),事故當下幾乎無人能鎖定前十分鐘曾經做過的變更。
昨天的內容雖然將變更內容都留下了,但還是落在某位同仁直接進行變更,然後生效的狀態。
今天筆者要來介紹Pull Request
是可以如何進行團隊共同審查,而且可以透過這個階段,預先進行一些檢查的動作。
甚麼是Pull Request
?從字面上來看,這是一個拉入的請求,讀者可以想像成,main
分支具備了所有環境的描述設定檔。如圖23-1範例中,清楚描寫了SIT
環境中的kong.yaml:v1
是當下的描述狀態。如果之前像之前一樣讓團隊自由的去變更main
分支,那災害可能馬上就會發生,而且沒有人會馬上意會過來發生了甚麼事情。
在這前提之下,必須要把main
分支給保護起來,不讓任何人可以直接而隨意的變更。而Pull Request
中,則是一個即將要變更受保護main
分支上kong
的描述檔的一個請求作業。這種做法有時候會讓人覺得厭倦,因為審查這個動作筆者相信就跟小時候考試一樣,沒人喜歡。
但如果為了確保目的與品質,而做的一個品質保證的確認與同步作業,那就不可或缺了。
圖23-1 Pull Request
讀者可以思考看看,是不是曾經有過不知道在哪裡的變更,而導致整個資訊單位兵荒馬亂?但最後發現可能只是某一位同仁忠實的執行某個需求單
上的要求,而造就了那一陣混亂。最終可能是剛好該同仁突然發現現場跟快燒起來了一樣而趕快變更回去,才解除那一陣讓大家心驚膽怕的過程。
而Pull Request
的這個作業不只是做人為的審查,通常更不是只是拿來做文件的審查,比較多的是用來做的是團隊之間的同步與討論。一方面確保變更被通知到相關團隊成員(出事當下大家馬上會想起這件事情),一方面藉由變更前的確認,讓團隊或是資深成員思考,是不是可能會造成某些問題的一個變更前確認。
接下來,筆者來示範如何將分支保護:
圖23-2 Branch polices
請讀者參考圖23-2,找到本次示範的Repo:Iac_Demo
中的Branches
,目前應該僅有main
分支被建立在那。這時候請點選main
分支最右邊那三個...,並選取Branch polices
。
圖23-3 Branch polices - settings
接著可以看到圖23-3 ,將上述選項設定起來就好,其他的項目則視需求設定。當這一步設定完成,如果有任何團隊成員要直接變更main
分支,就會跳出下列圖23-4的畫面,告訴你不能夠直接推送了。如果更細心去看VSCode
中的git錯誤訊息,就會發現訊息列要求要使用Pull Request
(圖23-5)來進行變更。
圖23-4 無法直接Push
圖23-5 要求發動Pull Request
如果已經設定好了Pull Request,勢必就需要團隊成員共同審查後,才可以在經過同意後執行。不過就算是個高手,用眼睛看yaml檔大概還可以理解變更的邏輯,但是當整個設定檔已經高達上千行時,不可能用人類的眼睛檢查所有內容,那是天方夜譚。
例如這次筆者準備要進行示範的案例,已經有135
行了。更別提公司內dump
出來時,那個近乎萬行的設定檔一定沒辦法用人力檢查。既然已經設定了預檢,接下來筆者更進階了來介紹,如何在預檢階段進行技術性的檢查,這時就不得不提decK
了。
decK 是一個命令列工具,專為 API 生命週期自動化(APIOps)設計,提供一套完整的指令工具組,用來協調與自動化 API 交付的整個流程。
筆者在公司中,通常會使用decK
與Control Plane
做互動,因為公司的協作模式就是透過修改yaml
後,確認要變更的內容,確定變更內容無誤且格式檢查也正確後,執行deck sync
的指令進行變更作業。
這次筆者準備用來做格式的檢查,讀者可以先關注到示範檔案ironman2025\case_ELK_JPG_Route_HMAC\Iac_Demo\pipelines\deck_check_all.yaml
,先剖析要執行的內容。
trigger: none
pool:
vmImage: 'windows-latest'
stages:
- stage: 'deck_Verify'
displayName: 'deck_Verify'
jobs:
- job:
steps:
- checkout: self
fetchDepth: 0
- task: PowerShell@2
displayName: 'Verify Kong Declarative Config'
inputs:
targetType: 'inline'
script: |
cd $(System.DefaultWorkingDirectory)
# 比對本地 origin/main 與目前 HEAD 之間所有異動的 yaml 檔案,並排除 pipelines 資料夾
$diffFiles = git diff --name-only origin/main...HEAD | Where-Object { $_ -like "*.yml" -and $_ -notlike "pipelines/*" }
if (-not $diffFiles) {
Write-Host "No changed yaml files detected."
exit 0
}
$failed = $false
foreach ($file in $diffFiles) {
Write-Host "Validating $file ..."
try {
.\deck file validate $file
} catch {
Write-Host "Validation failed for $file"
$failed = $true
}
}
if ($failed) {
Write-Error "Some yaml files failed validation."
exit 1
}
簡單的說明一下上面的yaml
,要注意兩個重點就好:
check out
的 fetchDepth: 0
,這是為了將整個git tree fetch下來,雖說這個動作會減緩速度,但是這是為了可以比對本次pull request
與main
分支的差異檔案而設定。task: PowerShell@2
的目的是,將所有這次變更的yml
檔案(因為kong設定檔這裡用的是yml
)都找出來,並排除/pipelines
資料夾。接下來讓decK進行 .\deck file validate $file
的檢查,已確認格式以及邏輯都合格,讓審核者可以安心按下那個許可按鈕。因此,當完成了前一個段落寫的pipeline yaml
後,接下來將該檔案設定成pipeline
(設定步驟與Day 21相同,這裡命名為Check kong config via decK
),接著就回到圖23-3 的下方,可以找到圖23-6的畫面。
圖23-6 Build Validation
到這裡,基本上已經完成了Pull Request
的預先驗證作業了。
接下來,由於前一天還有一個議題,那就是如果遇到緊急狀況時,要還原實在太慢了。因為變更管理需要一個審核的流程,對於開發人員來說相關的程式碼都已經在多個環境(DEV/SIT/UAT)經過不少驗證了,只要確保程式碼是對的那一包,基本上就剩下設定的問題。
但前面有說的,Infrasture
設定的變更,有時候在不同環境可能無法模擬一模一樣的驗證(錢真的多到滿出來可能可以吧)。因此筆者認為IaC
的透過pipeline
的自動化變更,一定要搭配快速還原的特性,這樣才可預防因為環境變更不當造成的衝擊過長,特別是對正式營運的環境。
先看到示範專案中另外一個yaml檔案(pipelines\SIT_Kong_sync_and_rollback.yaml
),下面截錄部分內容:
...觸發條件同前省略...
stages:
- template: tmp_kong.yaml
...同SIT_Kong_sync.yaml 省略
- stage: ManualApproval
displayName: 'Manual Approval'
dependsOn: SettingKong
jobs:
- job: 'WaitForApproval'
displayName: 'Wait for Manual Approval'
pool: server
steps:
- task: ManualValidation@0
inputs:
notifyUsers: 'samnchiu@hotmail.com'
instructions: 'Please approve or reject the deployment.'
- template: tmp_kong_rollback.yaml
parameters:
environmentName: 'Demo SIT'
docker_compose_path: 'C:/Users/samnc/2025_ironman/ironman2025/case_ELK_JPG_Route_HMAC'
kongDeployConfigPath: '1.Kong_declarative/declarative'
kongConfigPath: 'SIT/Kong_declarative/declarative'
讀者可以注意到,在昨天介紹的pipeline
的基礎stage
下方,又建立了兩個stage
,簡單說明如下:
stage: ManualApproval
pool: server
這要特別注意,因為這個執行類型不能執行在ms-hosted agent
或self-hosted agent
,這是為了搭配下方的taskManualValidation@0
的必要設定。
task: ManualValidation@0
這則是這個stage的重點,這裡提供了一個人為互動的工作,希望審核者可以確認整個變更管理是否有成功。template: tmp_kong_rollback.yaml
stage
一樣,都是引用了一個範本yaml,相關參數不細說,直接進入範本yaml說明。輸入參數同前省略...
stages:
- stage: 'RollbackKong'
displayName: 'Rollback Kong Config'
dependsOn: ManualApproval
condition: failed()
jobs:
- deployment: 'RollbackKong'
....環境參數同前省略....
strategy:
runOnce:
deploy:
steps:
- task: PowerShell@2
displayName: '還原 kong.yml 並重啟 Kong'
inputs:
targetType: 'inline'
script: |
cd ${{ parameters.docker_compose_path }}/${{ parameters.kongDeployConfigPath }}
cp kong.yml.bak kong.yml
cd ${{ parameters.docker_compose_path }}
docker compose restart kong-dbless
Write-Host "已還原 kong.yml 並重新啟動 Kong"
同樣要注意到幾個重點,列點如下:
condition: failed()
,這步驟很重要,因為這是建立在前一個的stage如果失敗,則會觸發這個stage執行。- task: PowerShell@2
這則十分容易理解,這個步驟會把stage 1 原本有備份的kong.yml.bak
蓋回來,接著重新啟動docker compose。最後,記得將昨天原本設定的pipeline
(之前取名叫做SIT - Kong yaml
)指向新的tmp_kong_rollback.yaml
。可以在pipeline
點選edit
後,在編輯視窗可以點選右邊的更多功能,然後選擇新的yaml就可以了。可以參考圖23-7 與圖23-8。
圖23-7 將pipeline 設定新的yaml - 1
圖23-8 將pipeline 設定新的yaml - 2
今天的內容非常的長,因為筆者希望可以一次說明要處理前一日IaC
在變更管理時,會最擔心的預檢與快速還原。變更管理是一種流程的引入與改變,通常都要可以契合原始的需求。這些原始的需求都建立在作業人員長期例行性的工作,因此都已經有既有工作流與模式,通常也會有標準作業程序。
標準作業程序固然有其優點,但當那些作業程序過於僵化或過於繁冗,人工作業還是很容易做錯。因此筆者希望要能夠解決變更管理的基本需求外,同時間也可以將原有程序中的重複性卻又是不可或缺的優勢,進行自動化。這樣才能夠將一個成功的流程,推入組織的不同團隊。
雖說設定都完成了,但是相信讀者暫時還沒辦法想像,如何經歷一個完整的變更管理流程。明天開始,筆者將示範在這個變更管理的流程中,真實會看到的那些畫面。
明天見~