成果物管理 (Artifact Management) 是每個 CI/CD 管道中雖不起眼但至關重要的支柱。DOP-C02 在任務陳述 1.3(「建置與管理成果物」)下對其進行測試,且題目很少只是皮毛 —— 它們會深入探討跨帳戶 ECR 存取、CodeArtifact 上游儲存庫鏈、舊構建成果物的 S3 生命週期政策、用於 AMI 管道的 EC2 Image Builder、ECR 映像掃描配置,以及用於容器映像簽署的 AWS Signer。每種成果物類型(套件、容器、二進位檔、AMI)都有其專屬的 AWS 服務、許可模型和生命週期控制項。
本指南統一了跨 CodeArtifact (npm, Maven, PyPI, NuGet)、ECR (Docker 和 OCI 映像)、S3 (其他所有內容) 以及 EC2 Image Builder (AMI 和容器映像) 的成果物管理故事。它涵蓋了 DOP-C02 喜歡測試的跨帳戶模式、用於成本控制的生命週期政策、用於合規性的映像掃描、用於多區域韌性的複寫,以及用於供應鏈完整性的簽署。學完本篇後,你應該能夠應對任何成果物管理問題,並能毫不混淆地挑選出正確的服務、生命週期和存取控制方案。
為什麼成果物管理橫跨了半個 SDLC 自動化領域
成果物 (Artifacts) 是建置過程的持久產出物 —— 即從建置流向部署的東西。如何存儲它們、如何進行版本控制、誰可以讀取它們以及何時刪除它們,是每個管道中都會反覆出現的決策。考試將成果物管理視為專業級 (Pro-tier) 主題,因為錯誤的服務選擇(例如,對 npm 套件使用 S3 而非 CodeArtifact)會產生營運債務、安全漏洞和成本激增。
三種力量形塑了成果物管理的決策空間。首先是 成果物類型 (artifact type):套件 (npm/Maven/PyPI/NuGet) 屬於 CodeArtifact,容器映像屬於 ECR,AMI 來自 Image Builder,其他所有內容則放在 S3 中。混用類別會導致流程不順。其次是 存取模式 (access pattern):開發人員在每次建置時都會從成果物存儲庫拉取內容,且通常是跨帳戶的;存取模型必須能擴展到每天數千次拉取,且延遲需低於一秒。第三是 生命週期 (lifecycle):成果物累積速度很快(每次提交、每次建置、每個發行標籤);如果沒有生命週期政策,S3 和 ECR 的帳單會失控,且安全風險也會擴大。
- CodeArtifact: AWS 託管的套件登錄檔,支援 npm、Maven、PyPI、NuGet 和通用套件。
- CodeArtifact 網域 (domain): 儲存庫的邏輯容器,提供單一 KMS 金鑰並跨儲存庫整合計費。
- CodeArtifact 儲存庫 (repository): 網域內按團隊或用途劃分的套件存儲庫;可以連結到上游儲存庫。
- CodeArtifact 上游儲存庫 (upstream repository): 當快取未命中時,另一個儲存庫會從中獲取內容的儲存庫;支援與 npmjs、Maven Central、PyPI 的公共連接。
- ECR 私有登錄檔 (private registry): 每個帳戶、每個區域的容器映像登錄檔,具有按儲存庫劃分的政策。
- ECR 公共登錄檔 (public registry) (
public.ecr.aws): AWS 用於分發開源映像的免費公共登錄檔。 - ECR 生命週期政策 (lifecycle policy): 一組 JSON 規則,可按標籤模式、天數或計數自動刪除映像。
- ECR 複寫 (replication): 跨區域和跨帳戶自動複寫映像。
- EC2 Image Builder: 用於建立 AMI 和容器映像的託管管道服務,包括修補、強化和基於標籤的生命週期。
- AWS Signer: 用於 Lambda 部署套件和 OCI 容器的程式碼簽署服務。
- 參考資料: https://docs.aws.amazon.com/codeartifact/latest/ug/welcome.html
白話文解釋 Artifact Management
成果物管理在概念上很平凡,但很容易被誤用。來自不同領域的三個類比可以讓生命週期和存取模型變得具體。
類比 1:圖書館編目系統
想像一個管理著數百萬本書籍、期刊和微縮膠片的巨型研究圖書館。CodeArtifact 就是 期刊室 —— 每一期期刊(每個 npm 套件的每個版本)都被編目,並帶有引用鏈,因此引用舊卷的論文仍能定位到它(版本化套件解析)。網域 (domain) 就是 圖書館大樓 —— 它擁有空調控制 (KMS 金鑰) 和編目系統。儲存庫 (repositories) 是大樓內按團隊或主題組織的 書架。上游儲存庫 (upstream repositories) 則是 館際互借協議 —— 當研究人員請求本地書架上沒有的書時,管理員會從中央系統 (Maven Central, npmjs) 獲取並在書架上保留一份副本供下一位讀者使用。
ECR 是 特藏庫 —— 存放大型、受版本控制的成果物(稀有手稿、容器映像),需要存取控制和防篡改證明。S3 是 一般儲存倉庫 —— 存放任何不符合期刊室或特藏庫編目規則的東西。
生命週期政策 (lifecycle policy) 是 除藏政策 (deaccessioning policy) —— 定期清理書籍和微縮膠片(30 天后捨棄未加標籤的映像,修剪舊版本以保留最新的 50 個)。如果沒有除藏政策,圖書館會耗盡書架空間,其目錄也會變得無法檢索。
類比 2:餐廳儲藏室和走入式冰箱
餐廳廚房跨多個存儲區管理易腐物品。走入式冰箱 是 CodeArtifact —— 每種食材(套件版本)都貼有日期、供應商(上游)和有效期限標籤。冷凍櫃 是 ECR —— 用於長期存放預製組件(容器映像),可按需解凍。乾貨儲藏室 是 S3 —— 用於大宗存放穩定、不易腐爛的物品(建置成果物)。
跨帳戶存取 (cross-account access) 是 中央廚房合作夥伴關係:姐妹餐廳有自己的儲藏室,但在繁忙的夜晚,主廚持有簽署過的許可單,可以從合作夥伴的走入式冰箱中抓取特定物品。資源政策 (resource policy) 是貼在合作夥伴冰箱門上的 合作協議,詳細列出了借用者可以拿走的物品。
映像掃描 (image scanning) 是 食品安全檢查 —— 每個容器映像在被允許拉取之前都要進行漏洞掃描,就像每批貨物在進入冰箱前都要檢查是否變質一樣。
類比 3:製造業零件倉庫
航空航太製造商維護著一個具有嚴格出處和可追溯性的零件倉庫。CodeArtifact 是 認證零件架 —— 每個零件號都標有供應商、批次和檢驗證書(npm 套件版本、登錄檔來源、完整性雜湊)。ECR 是 組裝子組件庫房 —— 發動機、航空電子模組、容器映像 —— 每個都有序號並通過檢驗認證。EC2 Image Builder 是 組裝加工線 —— 獲取原材料(基礎 AMI),通過加工和認證(建置組件、測試組件),輸出可供安裝的完成子組件。
AWS Signer 是 檢驗員的印章 —— 每個認證零件在檢驗站都會收到一個防篡改封條;下游操作會拒絕使用沒有封條的零件。
圖書館類比對於理解版本化套件解析和上游鏈最有用。廚房類比最能對應到跨帳戶存取和資源政策。當考試強調供應鏈完整性、簽署和映像掃描時,航空航太類比是正確的模型。參考資料: https://docs.aws.amazon.com/codeartifact/latest/ug/welcome.html
CodeArtifact 套件登錄檔
CodeArtifact 是 AWS 的託管套件登錄檔,支援 npm、Maven (Java)、PyPI (Python)、NuGet (.NET)、通用套件和 Swift 套件。兩層層次結構 —— 網域 → 儲存庫 —— 實現了關注點分離:網域擁有計費和 KMS 加密,儲存庫則擁有各個團隊的存取控制。
CodeArtifact 最重要的概念是 上游儲存庫 (upstream repositories)。團隊專屬儲存庫 (team-frontend) 宣告一個指向組織共享儲存庫 (shared-vendor-mirror) 的上游,後者進而宣告指向公共連接 (npmjs, pypi, maven-central) 的上游。當團隊請求套件時,CodeArtifact 在快取未命中時遍歷上游鏈,從公共連接獲取,在每一層進行快取並提供回應。隨後全組織範圍內的請求都會命中快取。
這種模式帶來了兩個優勢:(1) 依賴項整合 (dependency consolidation) —— 每個團隊的 npm install 都會填充單一的組織級快取;(2) 漏洞遏制 (vulnerability containment) —— npmjs 上的惡意套件在被獲取一次之前無法毒害組織;組織級的審核門檻可以在獲取前封鎖特定的套件名稱。
身分驗證透過 aws codeartifact get-authorization-token 使用短效(12 小時)權杖。CodeBuild 整合方式是在 pre_build 中執行此命令並將權杖匯出到語言工具(npm config set //... -auth ${TOKEN})。
上游鏈模式意味著開發人員針對單一 CodeArtifact 端點配置其工具,而永遠不會直接存取 npmjs 或 PyPI。這實現了:(1) 快取以減少外部頻寬;(2) 可用性 —— 公共登錄檔中斷不會影響具有快取套件的建置;(3) 政策執行 —— 在組織級儲存庫獲取前,封鎖已知的惡意套件名稱。參考資料: https://docs.aws.amazon.com/codeartifact/latest/ug/repos-upstream.html
ECR 容器映像
ECR 是 AWS 的容器映像登錄檔。每個帳戶在每個區域都有一個私有登錄檔 (<account>.dkr.ecr.<region>.amazonaws.com);登錄檔內的儲存庫保存各個映像流。
三個與考試相關的功能:
生命週期政策 (Lifecycle policies) 按標籤模式、計數或天數自動刪除映像。一個標準政策示例:「保留最後 10 個標有 prod-* 的映像,刪除超過 7 天的未標籤映像,刪除超過 30 天的 dev-* 映像」。如果沒有生命週期政策,ECR 帳單會按每映像 $0.10/GB-月累積。
映像掃描 (Image scanning) 在推送時執行(基礎掃描,免費)或持續執行(透過 Amazon Inspector 進行增強掃描,付費)。掃描結果發送 EventBridge 事件,並與 Security Hub 整合。大多數合規框架都要求進行掃描;考試將未掃描的映像視為安全缺陷。
跨帳戶與複寫 (Cross-account and replication) 允許一個團隊的建置推送到中央登錄檔,並將映像複寫到取用團隊的帳戶以及其他區域進行災難恢復 (DR)。複寫使用 ECR 私有登錄檔複寫規則(帳戶 + 區域對);來源登錄檔的設置驅動複寫過程。
ECR 儲存庫政策(基於資源)允許跨帳戶拉取;結合取用角色的 IAM 政策以獲得完整存取權限。
S3 構建成果物
對於不適合 CodeArtifact 或 ECR 的所有內容 —— zip 包、原始碼封存、CloudFormation 範本、建置日誌、簽署的二進位檔 —— S3 是萬能容器。CodePipeline 的成果物存儲區是一個 S3 儲存桶。CodeBuild 輸出成果物也存放在 S3 中。
成果物管理的關鍵 S3 模式:
版本控制 (Versioning):啟用儲存桶版本控制,以便即使在覆蓋或刪除後也能透過版本 ID 檢索成果物。這是任何合規性審計軌跡的必備要求。
生命週期政策 (Lifecycle policies):在 30 天後將舊成果物轉換為 S3-IA 或 S3-Glacier-Instant-Retrieval,並在 365 天後刪除。在高頻管道上,節省的成本非常可觀。
KMS 加密 使用客戶受管金鑰,並配合拒絕未加密 PutObject 的儲存桶政策。
對象鎖定 (Object Lock) 在合規模式下用於法律保留要求的成果物(例如簽署的發行版本二進位檔)。一旦鎖定,任何人都無法刪除對象 —— 包括根帳戶 —— 直到保留期結束。
S3 對象鎖定有兩種模式:監管 (governance) 模式(管理員可以覆蓋)和合規 (compliance) 模式(包括根帳戶在內均不可覆蓋,直到保留期結束)。對於審計級別的成果物保留,合規模式是正確的,但也很無情 —— 意外地在錯誤對象上鎖定 7 年保留期意味著該儲存桶在 7 年內無法刪除它。請務必先在監管模式下進行測試。參考資料: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock-overview.html
EC2 Image Builder 用於 AMI 和容器映像
EC2 Image Builder 按排程產生經過強化的 AMI 和容器映像,將以前的手動或基於 Packer 的過程自動化。一個管道包含三個組件:
配方 (Recipe):宣告基礎映像和要套用的組件(安裝套件、強化設置、執行驗證測試)。
組件 (Components):可重複使用的安裝/配置邏輯單元,以 YAML 格式宣告。AWS 提供標準組件(Amazon Inspector、CloudWatch 代理程式、核心強化);自定義組件則執行 shell 或 PowerShell。
分發配置 (Distribution configuration):指定產生的 AMI/容器映像的目標帳戶和區域,以及標籤和 KMS 加密。
管道按排程(例如每月 1 號)執行,拉取最新基礎 AMI,套用組件,執行驗證,並分發新映像。輸出結果流向由 ssm:/aws/service/... 參數或基於標籤的查詢所引用的 Auto Scaling 啟動範本 (launch templates)。
對於 DOP-C02,關鍵在於了解 Image Builder 是 AWS 推薦的取代 Packer + CodePipeline 編排的方案。考試模式:「公司每月使用手動腳本執行黃金 AMI 修補;推薦一種自動化的 AWS 託管方法」 —— 答案就是 EC2 Image Builder。
AWS Signer 程式碼簽署
AWS Signer 簽署 Lambda 部署套件和 OCI 容器,產生防篡改的成果物。
對於 Lambda,在函式上配置程式碼簽署配置:在更新時僅接受來自列出的簽署描述檔的簽署套件。未簽署或簽署錯誤的套件在部署時會被拒絕,防止未經授權的程式碼進入生產環境。
對於容器,Signer 與 Notation 規格以及 AWS Signer 的容器簽署功能整合。ECR 拉取操作在允許映像進入部署前會驗證簽署。
當題目提到「驗證部署套件的完整性」、「緩解供應鏈攻擊」或「簽署成果物的法律要求」時,考試通常將 Signer 視為正確答案。
Lambda 的程式碼簽署配置在執行 UpdateFunctionCode 時拒絕未簽署套件。一旦版本發布,即使簽署描述檔隨後被撤銷,該版本仍保持有效 —— 已發布版本是不可變的。要撤銷生產中的版本,你必須發布一個新的(已簽署)版本並更新別名 (alias)。考試會測試這類場景:「我們撤銷了簽署描述檔,但錯誤版本仍在運行」;答案是「發布新版本並更新別名」,而非「撤銷操作會修復正在運行的版本」。參考資料: https://docs.aws.amazon.com/signer/latest/developerguide/Welcome.html
跨帳戶存取模式
DOP-C02 最常見的跨帳戶模式:中央成果物帳戶託管 CodeArtifact 和 ECR;各團隊或各環境的帳戶拉取成果物。
對於 CodeArtifact,網域政策 (domain policy) 加上 儲存庫政策 (repository policy) 這對組合授予其他帳戶中的委託人讀取權限。取用帳戶的 IAM 委託人需要 codeartifact:GetAuthorizationToken、codeartifact:ReadFromRepository 以及 sts:GetServiceBearerToken。在每個跨帳戶邊界配置一次。
對於 ECR,儲存庫政策 (repository policy) 足以處理跨帳戶拉取。取用者的 IAM 角色需要對特定儲存庫 ARN 具備 ecr:GetAuthorizationToken(登錄檔範圍、帳戶級別)、ecr:BatchCheckLayerAvailability、ecr:GetDownloadUrlForLayer 和 ecr:BatchGetImage 權限。
對於跨帳戶共享的 S3 成果物儲存桶,儲存桶政策和 KMS 金鑰政策都必須授予存取權限;當儲存桶使用客戶受管 CMK 加密時,兩者缺一不可。
常見陷阱模式
陷阱 1:將 npm 套件存儲在 S3 中,因為「我們已經有 S3 了」。這缺乏依賴項解析、完整性雜湊以及與工具鏈的整合。CodeArtifact 是為此專門設計的。
陷阱 2:缺失 ECR 生命週期政策。未標籤映像永久累積;帳單激增卻沒有任何功能價值。
陷阱 3:假設 ECR 跨帳戶僅需儲存庫政策。取用者在其自身角色上也需要 IAM 許可;雙方必須達成一致,就像 S3 一樣。
陷阱 4:啟用了 ECR 推送時掃描,但未訂閱結果。沒有警示的掃描結果只是噪音;需與 Security Hub 或 EventBridge 整合。
陷阱 5:在未先進行監管模式測試的情況下使用對象鎖定合規模式。合規保留是不可撤銷的。
跨帳戶 ECR 拉取同時需要來源帳戶的儲存庫政策(允許取用者委託人)和取用帳戶的 IAM 政策(允許對來源 ARN 執行 ecr:GetDownloadUrlForLayer 和 ecr:BatchGetImage)。許多考生誤以為資源政策就足夠了,因為 S3 跨帳戶是那樣運作的;但 ECR 遵循的是「IAM 加資源政策」模式。參考資料: https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html
端到端成果物架構
一個典型的 DOP-C02 多帳戶成果物架構如下組裝。工具帳戶 (Tooling account) 託管:一個 CodeArtifact 網域,其中包含一個 vendor-mirror 儲存庫(上游為 npmjs/pypi/maven-central)和多個將 vendor-mirror 作為上游的團隊儲存庫;一個 ECR 登錄檔,並複寫到取用者帳戶和 DR 區域;一個 CodePipeline 成果物儲存桶,具備 KMS 加密、版本控制和 90 天轉換到 S3-IA 的生命週期。Image Builder 管道 每月執行,產生經過強化的 AMI,並透過跨帳戶分發發送到取用者帳戶。Signer 描述檔 在建置時簽署 Lambda 套件和容器映像。
此架構清晰地將成果物生產(工具帳戶)與取用(工作負載帳戶)分開,透過複寫支援 DR,並透過簽署強制執行供應鏈完整性。
對於任何成果物管理問題,請鎖定:
- 按類型選服務:套件用 CodeArtifact,容器用 ECR,AMI 用 Image Builder,其他用 S3。
- 生命週期政策:每個成果物存儲區都需要明確的保留規則,以防止無限增長。
- 跨帳戶存取:資源政策 + 取用者 IAM 政策同步配合;若是客戶受管加密,還需 KMS 金鑰政策。
- 供應鏈完整性:映像掃描 (ECR)、程式碼簽署 (Signer)、對象鎖定 (S3) —— 每一項都對應不同的合規控制項。
任何成果物問題都可以映射到這四點之一。參考資料: https://docs.aws.amazon.com/codeartifact/latest/ug/welcome.html
常考陷阱(Common Exam Traps)
- 將 npm 套件存儲在 S3 中 —— 缺乏完整性雜湊、依賴項解析和工具整合;CodeArtifact 是任何「npm/Maven/PyPI 登錄檔」問題的正確答案。
- 無 ECR 生命週期政策 —— 未標籤映像永久累積;設置刪除「未標籤 > 7 天」並限制「標籤前綴為 dev」的規則是基本的維護常識。
- ECR 跨帳戶假設僅需資源政策 —— 取用側的 IAM 角色必須顯式允許對來源 ARN 執行
ecr:BatchGetImage;雙方許可均必備。 - 未經測試即使用對象鎖定合規模式 —— 不可撤銷;即使是 root 也無法在保留期結束前刪除鎖定對象。請先使用監管模式驗證政策。
- 期望 CodeArtifact 權杖長效有效 —— 權杖在 12 小時後過期;管道必須在
pre_build中調用get-authorization-token,而非將其寫死在映像中。
FAQ
Q1:為什麼使用 CodeArtifact 而不是自行託管的 Nexus 或 Artifactory? CodeArtifact 是完全託管的(無需修補節點),與 IAM 和 KMS 原生整合,支援與 Nexus 相同的上游鏈模式,且按請求計費而非按伺服器計費。僅當組織政策禁止使用託管服務,或你需要 CodeArtifact 尚不支持的套件類型時,自行託管才是合理的。
Q2:單個 CodeArtifact 儲存庫可以支援多種套件格式 (npm + Maven + PyPI) 嗎?
可以。一個儲存庫可以同時存放所有支援格式的套件。常見模式:一個 team-frontend 儲存庫同時存放 npm 和 Maven 成果物。
Q3:如何防止開發人員向組織儲存庫推送名稱重疊的惡意 npm 套件? 將組織級儲存庫的「外部連接」政策設置為僅允許特定的公共登錄檔連接,並啟用套件來源控制(「上游」或「內部」)。內部套件不能被具有相同名稱的上游套件覆蓋(從而避免依賴混淆攻擊)。
Q4:ECR 私有和 ECR 公共有什麼區別?
ECR 私有需要身分驗證,地址為 <account>.dkr.ecr.<region>.amazonaws.com。ECR 公共可匿名拉取(受 AWS 託管的費率限制),地址為 public.ecr.aws/<alias>/<repo>。對於你想讓全世界使用的開源映像,請使用公共登錄檔;內部成果物請使用私有登錄檔。
Q5:ECR 複寫如何與跨帳戶存取交互? 複寫將映像複製到目標登錄檔;存取控制仍獨立套用 —— 目標帳戶的儲存庫政策決定誰可以拉取。複寫不會自動授予存取權限;它只是把資料傳過去。
Q6:如何將 EC2 Image Builder 與我的 CodePipeline 整合? Image Builder 管道可由 CloudWatch Events / EventBridge 觸發,或透過 SDK 調用。在 CodePipeline 中,使用 Lambda 調用操作來啟動 Image Builder 管道並輪詢完成狀態,然後將新的 AMI ID 發布到 SSM Parameter Store,供下游 Auto Scaling 群組使用。
Q7:AWS Signer 支援存儲在 ECR 中的 Docker 映像嗎? 支援。Signer 與 Notation 規格整合,用於容器映像簽署。可將 ECR 配置為在映像拉取前要求簽署驗證(透過 Inspector 增強掃描政策和 Notation 工具)。
Q8:過期 S3 中舊的 CloudFormation 部署成果物的最簡單方法是什麼?
在成果物儲存桶上套用 S3 生命週期規則,使用前綴過濾器 (pipeline-artifacts/),對當前版本設置 Days: 90 過期,並對非當前(受版本控制)對象設置 NoncurrentDays: 30。這能在保留近期成果物以備回滾的同時限制成本。