examlab .net 用最有效率的方法,考取最有價值的證照
本篇導覽 約 25 分鐘

Lambda 部署 — Aliases、流量切換與 SAM Canary

5,000 字 · 約 25 分鐘閱讀 ·

DOP-C02 深度解析 Lambda 部署策略:別名 (alias) 與版本 (version)、加權流量轉移、CodeDeploy 金絲雀 (canary) 與線性 (linear) 組態、SAM 與 CloudFormation 部署偏好、基於警示的自動回滾,以及部署期間的預先佈建並行能力 (provisioned concurrency)。

立即做 20 題練習 → 免費 · 不用註冊 · DOP-C02

Lambda 部署在概念上是最簡單的無伺服器 (serverless) 操作,卻是 Pro 等級最不容易做對的事情。DOP-C02 考試期望考生熟練掌握 Lambda 的版本模型 (versioning)、基於別名 (alias) 的流量轉移、CodeDeploy 對金絲雀 (canary) 與線性 (linear) 部署的整合、AWS SAM 的 DeploymentPreference 縮寫語法、基於警示的自動回滾,以及部署期間預先佈建並行能力 (provisioned concurrency) 的隱藏陷阱。與 EC2 或 ECS 不同 —— Lambda 沒有執行個體 (instance) 或任務 (task) 需要排空 (drain) —— 流量轉移發生在別名層 (alias layer),因此整個部署敘事其實就是「把別名指向另一個(或加權的)版本」。

本指南從 version 與 alias 開始建立 Lambda 部署的心智模型。內容涵蓋何時使用原生 alias 更新、何時改用 CodeDeploy 託管的流量轉移、SAM 的 DeploymentPreference 如何簡化 CodeDeploy 配線、PreTraffic 與 PostTraffic hook 如何插入驗證流程、基於警示的自動回滾如何運作,以及預先佈建並行能力與版本汰換之間的微妙互動。讀完之後,你應該能看到任何 Lambda 部署情境題就立刻判斷答案是「用 alias」、「用 CodeDeploy 搭配金絲雀組態」或「用 SAM AutoPublishAlias 加 DeploymentPreference」。

為什麼 Lambda 部署需要 Pro 等級的思維

Lambda 部署在三個關鍵面向與 EC2 / ECS 不同。第一,版本不可變 (immutability at the version):每個已發佈的版本都是不可變的,這讓回滾變成只改 metadata 的操作(把 alias 指回舊版本)—— 不需重新部署程式碼。第二,alias 即路由層 (alias-as-routing-layer):alias 可同時對兩個版本進行加權路由(例如 90% 到 v5、10% 到 v6),完全不需動到基礎設施。第三,叫用端整合 (invocation-time integration):API Gateway、EventBridge、S3 事件、SNS、SQS 與其他叫用者都指向 alias,而非函數名稱本身;alias 是穩定的位址。

這三個特性合起來,使 Lambda 的部署模型特別適合金絲雀部署 —— 你就是調整 alias 權重而已。複雜度來自自動化:CodeDeploy 搭配警示式回滾把手動調權重變成全自動的金絲雀或線性部署,而 SAM 的 DeploymentPreference 把 CodeDeploy 設定濃縮成兩行 YAML。

DOP-C02 的題目傾向測試:(1) CodeDeploy 比原生 alias 更新多了什麼價值、(2) CodeDeploy Lambda 組態的逐字名稱、(3) PreTraffic 與 PostTraffic hook 的語義,以及 (4) alias 更新與預先佈建並行能力的互動。

  • Lambda version:函數程式碼與設定的不可變快照;以數字版本 (例如 12) 或 $LATEST(未發佈版本)識別。
  • Lambda alias:指向某個版本(或加權版本對)的具名指標,叫用者可指向 alias 而非 $LATEST;常見名稱:prodstaginglive
  • 加權 alias (Weighted alias):透過 RoutingConfig.AdditionalVersionWeights 將第二個版本映射到一個分數權重 (0.0–1.0) 的 alias 設定。
  • CodeDeploy Lambda 部署組態 (Deployment configuration):控制流量轉移排程的具名政策(例如 LambdaCanary10Percent5MinutesLambdaLinear10PercentEvery1Minute)。
  • PreTraffic hook:CodeDeploy 在轉移流量「之前」叫用的 Lambda 函數,用於驗證;非零回傳會中止部署。
  • PostTraffic hook:CodeDeploy 在流量完全轉移「之後」叫用的 Lambda 函數,用於部署後驗證。
  • AutoPublishAlias (SAM):SAM 的屬性,每次程式碼更新會自動發佈新版本,並把指定的 alias 指向該版本。
  • DeploymentPreference (SAM):SAM 的屬性,宣告函數的 CodeDeploy 組態 (Type、Hooks、Alarms、Role)。
  • 預先佈建並行能力 (Provisioned concurrency):預先暖機好的 Lambda 執行環境;綁定特定版本或 alias,部署期間有微妙互動。
  • 參考:https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html

白話文解釋 Lambda 部署

Lambda 部署的感覺與其他運算平台不太一樣,因為沒有機群可管理。以下三個跨領域的類比可以讓「基於 alias 的流量轉移模型」變得直觀。

類比 1:電話轉接服務

想像一間小公司有一個公開電話號碼,會自動轉接到當班的員工。公開電話號碼就是 alias —— 印在名片、電話簿上、給 API Gateway 與 EventBridge 用。特定員工的直撥分機就是 version —— 不可變,雇用時就固定。更新 alias 就是改轉接規則 —— 瞬時、原子性、來電者完全感受不到。

加權 alias通話路由魔法:90% 來電進到資深員工 (v5),10% 轉到新進員工 (v6) 接受評估。一週評估後若新人通話品質達標,路由切換到 100% 給新人。回滾就是把規則改回資深員工 —— 一次電話系統設定變更,不需要重新培訓或重新招人。

CodeDeploy 搭配金絲雀組態自動電話路由管理員:它按排程調整百分比(10% 維持 5 分鐘,然後 100%),監控客訴指標,若客訴飆升就自動把路由切回資深員工。PreTraffic hook面試篩選 —— 在任何真實顧客的來電進到新人之前,主管會先做模擬電話(合成測試);若新人連模擬都搞砸,就完全不會把真實流量轉過去。

類比 2:餐廳品嚐菜單試菜

高級餐廳要推出新菜。公開菜單上列出菜名(alias seared scallops)。後台,主廚有兩個食譜 —— v5 食譜(已驗證的做法)和 v6 食譜(新技術)。廚房進行金絲雀試菜:接下來的 10 份 seared scallops 訂單中,1 份用 v6(新技術),9 份用 v5(已驗證)。若 v6 的菜完美回到桌上,主廚下一輪服務把 v6 提高到 25%,然後 50%、最後 100%。

PreTraffic hook主廚試吃 —— 任何顧客拿到新食譜之前,主廚必須先試菜並確認過關。PostTraffic hook服務後回顧 —— 新食譜完全推開之後,主廚會檢視整個服務時段的顧客回饋,確認接受度。

類比 3:軟體 Beta 測試計畫

消費型軟體公司推出新功能 beta 計畫。產品 (alias) 在 App Store 上是單一個體。內部,version 是不可變的釋出版本 —— v5 是當前生產版,v6 是 beta。公司的推送系統第一天把 1% 使用者導到 v6、第二天 5%、第三天 20%、第四天 100%。當機回報就是 CloudWatch 警示 —— 若 v6 的當機率比 v5 多超過某個門檻,推送系統幾分鐘內就自動把所有人退回 100% v5。完全不需要工程師介入。

電話轉接類比最直接對應 alias 更新,對第一次接觸的學習者最直觀。餐廳類比最適合理解 hook 的語義。軟體 beta 類比最適合考題強調「百分比漸進部署 + 警示驅動回滾」的情境。參考:https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html

Version 與 Alias —— 一切的基礎

每個 Lambda 函數都從一個版本開始:$LATEST。它是可變的 —— 每次程式碼更新都覆寫它。發佈版本 (PublishVersion API 或 aws lambda publish-version) 會用當前的 $LATEST 做快照,建立一個不可變的數字版本(1、2、3...)。

Alias 是解析到某個版本的具名指標。一個 prod alias 可能指向版本 5;把 alias 更新到版本 6 就改變了 prod 進來的請求會打到哪份程式碼。Alias 支援加權路由prod alias 可以指向版本 5,並用 AdditionalVersionWeights: {6: 0.10} 將 10% 的叫用送到版本 6、90% 留在版本 5。

關鍵慣例:叫用者一律指向 alias,絕不直接指向 $LATEST。API Gateway 整合、EventBridge 規則、S3 事件通知、SNS 訂閱、SQS 事件來源都應該參考 function-name:prod,而不是 function-name(意義等同 $LATEST)。這讓 alias 更新成為唯一的釋出控制點。

CodeDeploy Lambda 部署組態

CodeDeploy 自動化「隨時間調整 alias 權重」。組態決定排程:

  • CodeDeployDefault.LambdaAllAtOnce:一次轉移 100%。等同原生 alias 更新;CodeDeploy 在這裡只多了 hook 與回滾。
  • CodeDeployDefault.LambdaCanary10Percent5Minutes:10% 維持 5 分鐘,然後 100%。
  • CodeDeployDefault.LambdaCanary10Percent10Minutes:10% 維持 10 分鐘,然後 100%。
  • CodeDeployDefault.LambdaCanary10Percent15Minutes:10% 維持 15 分鐘,然後 100%。
  • CodeDeployDefault.LambdaCanary10Percent30Minutes:10% 維持 30 分鐘,然後 100%。
  • CodeDeployDefault.LambdaLinear10PercentEvery1Minute:每 1 分鐘加 10%(共 10 分鐘)。
  • CodeDeployDefault.LambdaLinear10PercentEvery2Minutes:每 2 分鐘加 10%。
  • CodeDeployDefault.LambdaLinear10PercentEvery3Minutes:每 3 分鐘加 10%。
  • CodeDeployDefault.LambdaLinear10PercentEvery10Minutes:每 10 分鐘加 10%。

自訂部署組態 (Custom deployment configuration) 可定義非標準 SLA 所需的任意金絲雀或線性排程。

考題有時會給部分組態名稱讓你判斷是 canary 還是 linear。Canary 名稱永遠是 Canary{percent}Percent{minutes}Minutes(一個起始百分比,然後跳到 100)。Linear 名稱永遠是 Linear{percent}PercentEvery{minutes}Minute(s)(整段時間內均勻遞增)。掌握命名邏輯,就算沒背全部變體也能答對。參考:https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-configurations.html

SAM AutoPublishAlias 與 DeploymentPreference

AWS SAM 把整套 Lambda 金絲雀配線壓縮成兩個屬性:

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./src
      Handler: app.handler
      Runtime: nodejs18.x
      AutoPublishAlias: live
      DeploymentPreference:
        Type: Canary10Percent5Minutes
        Hooks:
          PreTraffic: !Ref PreTrafficHookFunction
          PostTraffic: !Ref PostTrafficHookFunction
        Alarms:
          - !Ref ErrorRateAlarm
        Role: !GetAtt CodeDeployRole.Arn

AutoPublishAlias: live 告訴 SAM (1) 每次程式碼變更時自動發佈一個新版本,並 (2) 確保 live 這個 alias 存在,且指向最新發佈的版本。

DeploymentPreference 宣告 CodeDeploy 組態:Type 選擇排程 (Canary10Percent5Minutes、Linear10PercentEvery1Minute 等),Hooks 列出 pre/post traffic Lambda 函數,Alarms 列出用於自動回滾的 CloudWatch 警示,Role 是 CodeDeploy 服務角色。

幕後,SAM 會把 CodeDeploy 應用程式、部署群組與部署組態以 CloudFormation 資源產出。考題很愛測:DeploymentPreference 只存在於 SAM,原生 CloudFormation AWS::Lambda::Function 沒有 —— 純 CFN 必須自己宣告 CodeDeploy 資源。

PreTraffic 與 PostTraffic Hook

Hook 是 CodeDeploy 在部署生命週期中叫用的 Lambda 函數,由部署帳號按標準 Lambda 費率付費。

PreTraffic hook 在新版本發佈完、但流量還沒轉移之前執行。用來對新版本做合成叫用(帶測試 payload),驗證基本功能。Hook 函數必須呼叫 aws codedeploy put-lifecycle-event-hook-execution-status --status Succeeded (或 Failed),告訴 CodeDeploy 是否要繼續。

PostTraffic hook 在部署完成(alias 完全指向新版本)之後執行。用來做端到端驗證 —— 合成 API 呼叫、整合測試、跨依賴服務的 smoke test。狀態通報模式相同。

典型的 PreTraffic hook 會用已知良好的測試事件直接叫用新版本並驗證回應格式;PostTraffic hook 則呼叫位於函數前端的 API Gateway 端點並驗證 happy-path 回應。

Hook 函數即使成功執行完,只要沒呼叫 PutLifecycleEventHookExecutionStatus,最終會超時(過了部署 timeout 之後),CodeDeploy 就會把它標記為 Failed。許多考生以為「hook 正常 return 就夠了」 —— 不夠。Hook 函數必須明確呼叫 CodeDeploy API 來回報狀態。參考:https://docs.aws.amazon.com/lambda/latest/dg/services-codedeploy.html

基於警示的自動回滾

CodeDeploy 可以在部署期間 CloudWatch 警示進入 ALARM 狀態時,自動把 alias 回滾。透過 DeploymentPreference.Alarms (SAM) 或 alarmConfiguration (原生 CodeDeploy) 設定。

最佳實踐警示:

  • 函數錯誤率Errors / Invocations > 1%(1 分鐘內)。
  • 函數執行時間:高優先函數 Average Duration > 1000ms
  • API Gateway 5xx 錯誤率:可捕捉到 Lambda 程式碼問題對下游的影響。
  • 來自 EMF 的自訂指標:透過嵌入式指標格式 (embedded metric format) 在日誌中嵌入的業務層級信號。

當警示在金絲雀或線性部署期間觸發,CodeDeploy 會停止排程並把 alias 回滾到舊版本 —— 因為只是 metadata 變更,所以是瞬時回滾。

預先佈建並行能力 (Provisioned Concurrency) 的互動

預先佈建並行能力會讓執行環境保持暖機狀態。它綁定到特定 version 或 alias,是部署期間微妙互動的來源。

如果預先佈建並行能力綁在 alias,權重轉移會按比例切分預先佈建容量。Alias 上有 100 PC、金絲雀 10% 到 v6 的情境,會變成 v6 有 10 PC、v5 有 90 PC。CodeDeploy 自動處理重新平衡。

如果預先佈建並行能力綁在特定 version,那個版本不論 alias 怎麼更新都保留自己的 PC。常見的部署模式:在流量轉移開始前先在新版本上預先配置 PC,這樣金絲雀流量就不會碰到冷啟動。SAM 的 ProvisionedConcurrencyConfig 可以綁到 alias 以取得這種自動平衡。

一個微妙的陷阱:部署一個 PC 綁在特定版本上的函數,但沒有在新版本上重新配置 PC,會讓新版本承受流量時冷啟動。除非有特別理由,否則永遠把 PC 綁到 alias。

綁到 alias 的 PC 會在金絲雀過程中自動重新平衡;綁到固定 version 的 PC 不會遷移到新版本。考題情境是「金絲雀部署導致使用者看到冷啟動」 —— 解法是把 PC 從 version 移到 alias。參考:https://docs.aws.amazon.com/lambda/latest/dg/provisioned-concurrency.html

比較 —— 原生 Alias 更新 vs CodeDeploy

Lambda 部署有三種做法,依自動化程度排序:

1. 原生 alias 更新 (UpdateAlias API):從舊版本瞬間切到新版本。沒有加權轉移、沒有 hook、沒有自動回滾。適用於非關鍵函數,回滾可接受是手動操作。

2. 手動加權 alias 更新:設定 RoutingConfig.AdditionalVersionWeights 並隨時間手動調整。能取得金絲雀語義,但需要操作員自己排程。在生產環境很少見。

3. CodeDeploy 搭配 DeploymentPreference:完整自動化,有排程流量轉移、hook、警示。生產環境的標準做法。

任何有明確 SLA、影響客戶、或需要警示式回滾的函數,預設選 3。內部自動化、排程批次作業或 ops 指令稿用 1。

CloudFormation 部署考量

透過原生 CloudFormation (AWS::Lambda::Function) 部署 Lambda 函數時,程式碼更新會就地取代 $LATEST。要取得版本語義,必須明確建立 AWS::Lambda::Version 資源 —— 但這些是不可變的,所以每次更新都需要一個新的邏輯資源 ID。

這就是 SAM 的 AutoPublishAlias 自動化掉的事情。沒有 SAM 的話,標準的原生 CFN 模式是把函數程式碼的 S3 物件版本編碼進 AWS::Lambda::Version 的邏輯 ID,強迫 CloudFormation 在每次程式碼變更時建立新的版本資源。

對 DOP-C02 而言,知道「Lambda CI/CD 偏好用 SAM」就夠了;你很少需要從零寫原生 CFN 模式。

常見陷阱模式

陷阱一:用 LambdaAllAtOnce 卻期待自動回滾接住問題。AllAtOnce 給你回滾機制但沒有金絲雀期 —— 警示觸發時,所有流量早已打到新版本。

陷阱二:API Gateway 整合指向 $LATEST 而非 alias。更新 $LATEST 會立即影響生產,沒有回滾路徑。

陷阱三:PreTraffic hook 沒呼叫 PutLifecycleEventHookExecutionStatus。Hook 靜默超時並讓部署失敗。

陷阱四:警示打在 alias 的指標上 —— CloudWatch 預設指標是每函數發出,不是每 alias。要對 alias 層級指標告警,要啟用 per-alias metric 或用 embedded metric format。

陷阱五:忘記在金絲雀流量轉移之前對新版本配置預先佈建並行能力;PC 綁在舊版本意味著金絲雀期間新版本會冷啟動。

CodeDeploy 自動回滾在相關警示進入 ALARM 時觸發。如果一個全新警示資料點不足(還沒任何資料點),它會維持在 INSUFFICIENT_DATA —— CodeDeploy 把這視為健康。對於剛建立的函數或警示,要確保基準指標已存在,再依賴警示式回滾。考題情境是「警示因為資料不足而沒觸發」。參考:https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-configurations.html

端到端 Lambda Pipeline 模式

DOP-C02 標準的 Lambda pipeline 組合長這樣。Source 在 CodeCommit。Build 在 CodeBuild 跑 sam build、跑單元測試、產出 packaged.yaml 與壓縮過的程式碼上傳到 S3。部署到 staging 透過 CloudFormation deploy action 對 SAM stack 設 DeploymentPreference: AllAtOnceApproval action 暫停等發佈經理簽核。部署到生產用同樣的 CFN deploy action 對生產 stack 設 DeploymentPreference: Canary10Percent5Minutes,PreTraffic hook 跑合成測試、PostTraffic hook 跑整合測試,警示打在函數錯誤率、執行時間及 API Gateway 5xx。

把這個模式背下來 —— 這是考題會出無數變體的參考架構。

任何 Lambda 部署題,都用這四件套定錨:

  1. Version 與 alias:叫用者指向 alias;alias 指向一個版本(或加權版本對)。
  2. CodeDeploy 組態:AllAtOnce(無金絲雀)、Canary{percent}Percent{minutes}Minutes(單一金絲雀步)、或 Linear{percent}PercentEvery{minutes}Minute(s)(均勻遞增)。
  3. Hook:PreTraffic(轉移前驗證)、PostTraffic(轉移後驗證);兩者都必須呼叫 PutLifecycleEventHookExecutionStatus
  4. 警示:綁函數錯誤率、執行時間、下游 API Gateway 5xx;進入 ALARM 觸發自動回滾。

SAM 的 AutoPublishAlias 加 DeploymentPreference 把 1–4 都包成兩個 YAML 屬性。參考:https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-deploymentpreference.html

常考陷阱

  1. 叫用 $LATEST 而非 alias —— 每次程式碼更新都立即影響生產且無回滾路徑;生產叫用者必須一律指向 alias。
  2. PreTraffic hook 漏呼叫 PutLifecycleEventHookExecutionStatus —— 即使執行成功,hook 會超時並讓部署失敗。
  3. 預先佈建並行能力綁在固定 version —— 金絲雀期間不會遷移到新版本;流量轉移時出現冷啟動尖峰。把 PC 綁到 alias 才會自動重新平衡。
  4. 警示處於 INSUFFICIENT_DATA 狀態 —— 自動回滾只在 ALARM 觸發;剛建立的警示如果沒資料點就不會發出。
  5. LambdaAllAtOnce 卻期待金絲雀安全性 —— AllAtOnce 立即轉移所有流量;警示仍會觸發回滾,但每位使用者早已碰過壞版本。

FAQ

Q1:什麼時候 CodeDeploy 比原生 alias 更新值得? 任何時候部署需要加權流量轉移、警示式自動回滾或 hook。原生 alias 更新適合 ops 指令稿和內部 Lambda。CodeDeploy 是面對客戶、有 SLA 的生產函數的預設選擇。

Q2:可以不用 SAM、單獨用 CodeDeploy 給 Lambda 嗎? 可以。在 CloudFormation 裡宣告 AWS::CodeDeploy::ApplicationAWS::CodeDeploy::DeploymentGroup,並手動連結到函數的 alias。SAM 把這些樣板隱藏起來;底層的 CodeDeploy 機制完全相同。

Q3:Lambda 部署期間,進行中的叫用會發生什麼事? 它們會用「叫用當下 alias 解析到的版本」執行完畢。Lambda 不會在流量轉移期間強制中止正在執行的呼叫。長時間執行的叫用可能在金絲雀開始之後才在舊版本上結束。

Q4:如何把 Lambda alias 回滾到指定的舊版本? 手動回滾:aws lambda update-alias --name prod --function-version 5 --routing-config AdditionalVersionWeights={}。CodeDeploy 回滾則是重新建立部署,用前一個成功 task-set 的版本作為目標。

Q5:CodeDeploy 是否支援 Lambda 的 EC2 式藍綠部署? Lambda 服務沒有多個「機群」 —— Lambda 的藍綠就是「版本之間的 alias 加權流量轉移」。概念上是藍綠(舊版本與新版本並存),但機制上是 alias 路由。

Q6:什麼時候應該選 LambdaLinear10PercentEvery1Minute 而不是 LambdaCanary10Percent5Minutes Linear 在整個部署窗口逐步遞增(Linear10PercentEvery1Minute 是 10 分鐘)。Canary 維持 10% 五分鐘後跳到 100%。Linear 對緩慢顯現的問題更安全;Canary 較快,足以對付快速失敗的 bug。

Q7:如何把 Lambda 函數部署與下游 DynamoDB schema 變更同步? 兩階段部署。(1) 先更新 DynamoDB 表(新增欄位、雙寫程式碼)。(2) 部署 Lambda 函數讀新欄位。(3) 回填舊資料。(4) Lambda 後續部署移除雙寫。用 Step Functions 狀態機包成編排;CodeDeploy 本身無法處理跨資源的序列化。

Q8:可以讓多個 Lambda 函數共用同一個部署組態嗎? 可以。一個 CodeDeploy 應用程式可有多個部署群組,每個指向不同函數的 alias。同一個自訂或預設部署組態可被多個群組參考。這是 monorepo serverless 應用(有大量函數)的標準模式。

官方資料來源

更多 DOP-C02 主題