紀錄 DevOps 相關名詞

最近聽到幾個沒有聽過的名詞覺得蠻值得記錄一下,也算是跟 DevOps 有關。 綠地專案 vs. 棕地專案: 我們站在什麼樣的基礎上開發? 這兩個詞彙本來是都市計畫的術語,我查是這樣,但我沒印象我大學時有學過,我記得以前是用「素地」來表示沒有建築物的土地。「素地」與「空地」不同,空地是指已有道路、排水、電力設施,可利用而仍未依法作建築使用,或已作建築使用,其建物價值不及基地申地價的 10%。 好,扯遠了,總之,這兩個詞用來比喻專案開發時所面對的環境。「綠地專案」指的是從頭開始的專案,而「棕地專案」指的是從既有的專案上開發。 對綠地專案而言,一切從頭開始,沒有既有專案的歷史包袱,理論上可以自由地選擇最新的技術、架構與工具,例如新創團隊開啟一個全新的專案,大概是這樣的概念。而相反地,棕地專案則像是在一塊已經開發過、甚至可能受到污染的「棕地」上進行翻新或擴建。開發團隊必須在既有的、可能充滿技術債的程式碼基礎上工作。例如我目前手上的專案全部都是棕地專案,充滿著大量 legacy code,牽一髮動全身的程式碼,讓我改起來膽戰心驚,到最後就很容易抱著能不改就不改的心態(If it works, don’t touch it.)。 總而言之,這表示在評估一個專案時,不能只看要開發的功能,更要理解它所處的狀況。是從零開始的創造?還是在既有框架下的奮鬥?這會影響策略的擬定。 平台工程(Platform engineering) 平台工程(Platform engineering)可將開發人員的部分工作和基礎架構相關手動作業移至 IDP(Internal Developer Platform),讓團隊能專心開發應用程式及投入創新1。 這聽起來有些抽象,但可以想像如果在一間公司中,AP 人員(開發團隊)需要自己處理伺服器、資料庫、CI/CD 等 infra 上,那就是一種資源的錯置,這會讓開發人員無法真正專注於在開發上2。平台工程團隊的角色,就是將這些繁瑣但必要的工作,整合成一個自助式的平台。開發人員可以透過這個平台,完成環境建置、部署、監控等任務。 在我們的場景,例如伺服器、資料庫這類 infra,是不需要自己建置,我們是透過需求單系統,填寫工單請專責人員建置3,這中間要經過層層關卡(雙方主管)的審核,最後才會成功把需求傳遞到專責人員手上開始作業。而作業過程中依據 SOP 需要留存大量的「軌跡」,這些軌跡最後都有可能會被稽核檢視其是否合規。簡單來說,有平台,但不好用。 至於 CI/CD,我們在導入 Azure DevOps 後算是有完成了這一塊拼圖,建立起一個可用的平台,畢竟我們原本的部署上線方式真的令人太痛苦了,這個有機會以後可以再分享一下。 https://cloud.google.com/solutions/platform-engineering?hl=zh-TW ↩︎ 在敝公司雖然不用自己建置基礎設施,但很多時候都要自己管理,因為我們的角色某種程度上是開發人員兼維運人員。 ↩︎ 在《獨角獸專案》這本書當中看到無極限零件公司裡面也要填寫類似的工單系統時,令我倍感熟悉。 ↩︎

July 16, 2025 · 1 分鐘

Azure ReplaceTokens 字串轉義問題

問題現象 在某個專案中,CI/CD 過程需要將設定以 token 替換的方式寫入 JSON 檔案,其中一個欄位包含多行文字內容。在 pipeline 中使用了 qetza.replacetokens.replacetokens-task.replacetokens@5 這個 Azure DevOps Task: - task: qetza.replacetokens.replacetokens-task.replacetokens@5 displayName: 'Replace token in xxx-config.json' inputs: targetFiles: '$(System.ArtifactsDirectory)\\drop\\$(Build.BuildId)\\xxx-config.json' 完成替換並部署到測試環境後,發現無法正常啟動。檢查部署產出的 JSON 檔案時,發現原本應為多行的字串中的 \n,在處理後變成了 \\n。 這導致程式在解析該欄位時,無法還原出原本的格式,進而發生錯誤。 問題原因 查閱文件後發現,ReplaceTokens 預設會對變數值進行 escape 處理。這對一般情況有幫助,但對於需要保留格式的多行字串(如憑證或編碼內容)就會導致格式錯誤。 解法:使用 noescape() 函數停用自動 escape ReplaceTokens 支援開啟轉換函數(Transformations)功能,可用來自訂變數處理方式。具體做法如下: 步驟 1:啟用 enableTransforms 在 ReplaceTokens 的 YAML 設定中加上 enableTransforms: true - task: qetza.replacetokens.replacetokens-task.replacetokens@5 displayName: 'Replace token in xxx-config.json' inputs: targetFiles: '$(System.ArtifactsDirectory)\\drop\\$(Build.BuildId)\\xxx-config.json' enableTransforms: true # 要加這行 步驟 2:修改 JSON,使用 noescape() 將目標檔案中的 token 改寫為: { "config_content": "#{noescape(multiline_config)}#" } 如此可讓 \n 在替換後仍保持原始格式,不會被轉成 \\n。 ...

July 9, 2025 · 1 分鐘

Azure Pipeline 編譯 iOS App Groups 權限未簽入問題

前言 公司原本的上線流程最近要走 Azure DevOps 方式上線,我維護的 iOS App 不外乎也要走這個流程。原本測試都沒有太大問題,但上線之後發現 App Groups 功能沒有正確運作,就開始查找問題,最終找到問題所在並解決,記錄一下過程,並延伸相關知識。 Trouble Shooting 一開始覺得很奇怪,這次上線的內容並沒有異動到 App Group 的設定,所以應該跟 source code 沒有太大關係。後來先嘗試在本機 build 一版,結果發現透過這個方式運作正常,但透過 Azure pipeline build 出來的就會發生問題。因此轉向研究 pipeline yaml 的設定是否出現狀況。 先進一步確認透過 Azure pipeline 包出來的 artifacts 內容是否正確,一般而言,iOS App 打包後的成品如下: DistributionSummary.plist ExportOptions.plist YourAppName.ipa Packaging.log 查看 .ipa 我們可以查看 YourAppName.ipa 裡面到底簽入了哪些權限: 解壓縮 .ipa 檔案: unzip YourAppName.ipa -d AppContents 進入 Payload 目錄: cd AppContents/Payload 執行 codesign 指令: codesign -d --entitlements :- YourAppName.app 每個部分的含義是: codesign:呼叫程式碼簽署工具 d:表示 “display”,用於顯示簽署資訊 -entitlements :-:要求工具顯示應用程式中包含的所有權限(entitlements) 這裡的 :- 是一個特殊的語法,表示將輸出導向到標準輸出(stdout) YourAppName.app:要檢查的應用程式套件路徑 如果有正確簽入 App Groups 的權限,應該要有 <key>com.apple.security.application-groups</key> 的蹤跡,但發現透過 Azure pipeline 包出來 .ipa 沒有。 ...

July 3, 2025 · 2 分鐘