﻿# 政府部門導入 DevOps 的挑戰與機會

在 2017 立冬之際，收到某個公部門資訊部邀約，希望我能前往分享 Git 版本控制。有趣的是，在講解 Git 版本控制的過程中，意外帶出該單位長久以來在系統委外管理上的困擾，從而演變成整場訓練大部分時間都在談 DevOps 的實務做法，大家相當踴躍的提出各種實務上遇到的問題，在一來一往問答的過程中，激盪出許多可以傳授的想法與觀念，而他們提出的各種問題，通通可以透過良好的 CI / CD 與 DevOps 規劃來解決！

![DevOps](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/d04d0be04a409e73508a-image_3162.png "DevOps")

這裡的 DevOps 指的是「開發維運一體化」，也就是一個應用系統如何從規劃、設計、開發到維運，再透過維運時期的監控回饋給開發團隊的一個過程。對公部門來說，導入 DevOps 的過程會牽涉文化、流程、制度、協作方式的改變，面臨的挑戰不小，實務上也鮮少聽到有公部門的成功案例。

### 緣起

公務機關的資訊單位因囿於人力，多將應用系統的開發及維運工作委外辦理。一般而言，承包商通常運用其自有的開發環境，在編譯完成並測試無誤後，部署到公務機關的營運環境，正式上線運作。

在實務運作上，各機關對程式部署的作法，可能不盡相同，但通常是要求承包商交付原始碼及編譯後的執行檔，由資訊單位承辦人員（包括系統使用者）在機關的測試環境測試無誤後，再部署到營運環境。其次，為了管控原始碼版本，程式部署到營運環境，必須再將修正後之原始碼置入版本庫，然而實務上亦曾發生於測試環境測試無誤但於營運環境出錯案例，於是急就章在營運環境主機上直接修正程式，只求正常提供服務，惟此修正後之程式碼並未置入版本庫，以至於版本庫與營運環境程式碼不一致；另承包商未將此修正後之程式帶回開發環境，導致後續開發之程式原始碼混亂情形。

另外，應用系統承辦人員對於系統架構或部署方式往往無法掌握，僅仰賴承包商全權處理，因系統異動頻繁，承包商所交付之系統文件亦常與實況不符；另承包商之專案人員亦常有異動之情形，整個系統彷彿黑盒子般，無人能完全掌握，也沒有詳實可靠的記錄，實對機關營運是一個重大風險。

### 透明化優先

從軟體開發的生命週期來看，大致可區分成規劃、開發、測試、部署、維運五大步驟，由於公務機關長年實施外包政策，每個應用系統除了規劃階段與測試階段會參與外，剩下的幾個重要步驟，幾乎都完全委外，專案的過程中雖然有文件產出，但囿於專案領域多元，應用系統承辦人員不太可能掌握細節，且整個過程缺乏有效的機制控管與追蹤，所以要克服導入 DevOps 的第一個挑戰，便是將整個過程透過版本控制系統詳實的記錄下來，將規劃、開發、測試、部署的過程完全透明化，讓系統凡走過必留下痕跡！

該部門早先已有建置 Subversion 版本控制系統，雖然有控管承包商所提交的程式碼，但嚴格說起來，只有做到「原始碼備份」而已，並不能稱上「版本控制」，對於應用系統的更新與部署，並沒有真正有效的進行管理。我們在本次建置與導入的過程中，採用分散式 Git 版本控制系統，並讓承包商從開發階段就能透過 Git 進行版控，每次提交上來的原始碼，也會包含完整的開發歷史紀錄。透過適當的權限控制，可以輕易做到提交過後的原始碼絕對不被竄改，徹底將開發階段的程式碼進行詳實的記錄。

不過，這個過程我們也遭遇到另一個挑戰，也就是特定承包商在當初承包的時候，就已經聲明不提供原始碼，只能提供可運行的二進位執行檔。對於這類沒有原始碼的專案，我們也能透過 Git 對這些檔案進行版本控制，這部分對於部署過程的透明化十分有幫助，任何一次的更新與部署都有完整的紀錄可追查。

### 文化的挑戰

導入 DevOps 的過程，通常會遭遇許多文化上的衝擊。就以該部門為例，要讓承辦人員學習 Git 分支與合併，就是一大難事。首先，承辦人員或許曾經寫過程式，但對於資深人員來說，寫程式的日子早已是滄海桑田，不用說「版本控管」可能從來沒用過，對於軟體開發過程中的常見的合併與衝突，其概念也是非常薄弱，不太清楚如何透過 Git 來整合承包商提交的程式碼，即便只是單純的合併作業，都有人抗拒學習。

在我根深蒂固的觀念中，我相信當你想學會一門技術或觀念，沒有學不會的事。所以導入的過程中，有個非常重要的事，就是主動學習的「動機」夠不夠強烈。透過良好的制度與流程改善，所有人都會動起來，搭配適當的教育訓練，短時間就能有成效。

如果你覺得文化的挑戰只來自於承辦人，那你就錯了。導入 DevOps 對承包商的文化衝擊，可能比你想像的還大。怎麼說呢？你可以想像一個情境：如果一個承包商，開發系統並未要求版本控管，而且人員更替頻繁，每次應用系統部署都是一場挑戰，由於沒有人能掌握原始碼的品質，經常要在部署的過程中投入大量時間進行現場手動測試。當你跟他們說，你們做過的所有事情都要透明化，所有的原始碼與部署的檔案都要進行詳實的記錄，請問你會怎麼想？

文化的挑戰不是一朝一夕就能克服，但只要方向正確，抱持著漸進式改善的敏捷精神，我相信克服文化的挑戰只是時間問題。

### 整合的挑戰

在推動 DevOps 的過程中，我們將建構與部署過程轉化為電腦可執行之自動化腳本，藉由持續整合(CI)平台，將每一個版本的原始碼自動化的完成建置作業，確保承包商提交的原始碼都是正確可建構的版本，這是確保應用系統品質重要的第一步。這個步驟並不是說程式碼可以正確運行，還單單只是可以成功透過工具進行建構而已。從經驗上來看，承包商提交一份無法建置的原始碼，比例之高會讓你難以想像。

接著我們會將建置成功的產出，進行自動化的應用程式部署，減少人工手動搬檔負擔與操作錯誤風險，也能有效縮短部署時程。由於持續整合要求將整個應用系統，從原始碼到可部署的產出自動化，如此一來便可確保承包商提交的程式碼與營運環境的程式完全一致，大大提升應用系統部署的能見度(Observability)。

在以往的日子裡，承包商必須先請工程師將部署至營運環境的程式檔案準備好，直接帶來現場更新與部署。但對於一個複雜的應用系統來說，光是從原始碼到產出可執行檔的整合過程可能極其複雜，當中會需要用到的開發工具、第三方元件、需要調整的設定檔，通常都沒有被完整記錄，而繁雜的背景知識也只會存在於工程師的個人經驗裡。

所以我們常會看到一種狀況，承包商請工程師來到現場部署程式，即便都有在測試環境測試過，但部署到營運環境卻還是發生問題，而且必須要讓有經驗的工程師在現場修復程式，而這個過程經常會耗用大量時間，而且當下修正的程式碼還不一定會回到程式碼版控控制，這樣的部署流程著實亟需改善。如果承包商的技術人員更替頻繁，這部分的整合知識就會有斷層，導致沒有人知道完整的部署流程，只能走一步算一步，每一次的部署都是場賭注。

我們在本案導入的過程中，流程的挑戰可謂相當嚴峻。首先，我們會先請承包商提供系統建構與部署步驟，但承包商經常無法提供完整可驗證的整合步驟。因為在建置與部署的過程中，都會有許多部署環境的注意事項，許多部署經驗早已遺失，我們只能在每次失敗的過程中學習經驗，並把每次的經驗整理成自動化腳本，逐步改善每個應用系統的整合流程。

### 成功的經驗

本案總共輔導了五個應用系統，導入過程最成功之系統，有許多值得借鏡的地方。

首先，應用系統承辦人相當支持 DevOps 這個概念，且在專案執行的過程中主動投入改變，不但進一步理解該應用系統之整體架構與部署方式，也強力要求承包商配合變更交付方式，幫助整個持續整合(CI)與持續交付(CD)的過程順利達成。

話雖如此，導入的陣痛期還是有的，一開始也是遇到承包商所保有的原始碼與本院主機不符的狀況，例如因為某次修改異動 5 支程式碼，承包商交付這批程式碼，但無法在本院主機上順利執行，後來查出，原來這 5 支程式碼與另 1 支非本次交付之程式關聯。而此支程式在本院主機上為舊版本與承包商開發環境之版本不一致，故導致本次交付之程式測試失敗。經過幾次的部署與測試磨合，目前已經可成功透過 CI/CD 機制部署至營運環境。

本案的成功經驗，無疑帶來雙贏的結果，承包商無須舟車勞頓到現場部署程式，資訊處同仁也不再需要透過繁複的人工程序手動部署，雙方都可受益於 CI/CD 帶來的效益，更能專注於應用系統的開發與維運。

### 失敗的經驗

本次導入過程最不順利的系統，參雜了許多不利本案導入的因素，對日後導入其他應用系統的過程，也有相當值得參考的地方。

第一，承包商負責開發應用系統的工程師異動頻繁，開發與部署的經驗無法傳承，從本案導入 DevOps 初期就遭遇不少困難，整合的過程也必須不斷從錯誤中學習，我們也投入了大量時間協助承包商釐清各種問題。

再者，應用系統承辦人員對於系統架構亦不熟悉，我們在導入過程發現有部分站台已不再使用，但仍存在於部署流程之中。多餘無用的站台，會造成資安方面的疑慮，透過本案導入自動化/透明化的過程，發現了許多長年沒被發現的潛在風險，也順利將部署流程改善。

更有甚者，承包商由於本身原始碼管理不善，其交付營運環境之原始碼，好幾次因為提交錯誤的版本，導致自動化部署的過程發生失敗。而該案因缺乏上線前的測試環境，無法提供一個有效的驗證環境，自動化部署的過程，反而更容易導致營運環境出現服務中斷的情況。

### 未來展望

我們從這次專案的經驗中，已經建構出一套可以自動化建置與部署的平台，在不久的將來，也可透過這個平台，進一步優化應用系統的交付流程，更能夠強化院內應用系統委外管理的流程，提升交付品質。以下列出幾個可以在短時間內改善的方向：

1.  源碼掃描與分析
    
    由於應用系統已經可以從程式碼版控到自動化建置與部署，這個過程可以在系統建構前後整合原始碼分析與網站弱點掃描工具，強化應用系統的資訊安全，也進一步保障軟體品質。
    
2.  議題與追蹤管理
    
    應用系統在交付上線後，通常會進入系統維護期，這個期間程式碼也會不斷異動，以往這些資訊都透過 E-mail 或 Word 文件的方式保存，相當不容易整合與管理。現在，我們可以將每次的程式問題、需求變更、功能改進，全部透過議題追蹤管理平台進行控管，並且與開發中的程式碼版控進行結合，讓每一段程式碼都能與實際需求結合。如此一來更能夠掌握每次系統調整所帶來的衝擊，也可以藉此學習並累積更多應用系統維運的知識與經驗。
    
3.  導入自動化測試
    
    應用系統在交付的過程，大多透過人工測試進行驗證，當應用系統過於複雜時，便無法全面檢測，只能測試系統重要部分。在實務上常會有改 A 壞 B 的情況，明明請承包商修改一個小功能，但是其他的功能卻壞掉了，這件事在業界也是屢見不鮮。這部分可以在應用系統發包初期，就明訂自動化測試的比例，也許不是 100% 自動化測試，但就算能達到 20% 的自動化測試，並在日後逐步改進，也是相當值得推展的目標。
    
4.  網站防竄改機制
    
    藉由已保存部署至營運環境之原始碼/程式碼及相關套件，我們很容易透過自動化程式腳本與營運環境之程式進行比對，如有非經授權，甚至是直接於營運主機上修改程式之狀況，皆可自動偵測出來，並主動發送檔案異動通知，加強資訊安全的防護能力。
    
5.  導入容器化技術
    
    容器化技術 (Container Technology) 在業界逐漸普及，原因就在於應用系統若透過容器的封裝與部署，可以大幅降低自動化部署的複雜度，同時降低部署環境的建置成本，更有效率的利用現有 IT 基礎建設，減少資源的浪費。
    

### 結語

DevOps 是一種文化，一種願意面對問題並持續改善的過程，我們可以藉由透明化來讓所有人認知到應用系統的開發與部署流程有改善的空間，並且透過自動化建置與部署來改善交付的品質。我們可以從日常的工作中累積出最佳實踐，並透過不斷的回饋，提升軟體與應用系統的品質。

如果有讀者對於導入 DevOps / CI / CD 有興趣，也歡迎填寫我們公司的 [服務需求表單](https://web.archive.org/web/20200809003836/https://docs.google.com/forms/d/e/1FAIpQLSf-hVyuAtNdOSyGxiadmH0ybIe9bJrxepj3nTdEBkoHaJj1Vw/viewform)，看是預約**顧問諮詢**或**演講邀約** 都可以安排時間到貴單位做更深入的分享。
