AWS CloudFormation 是 SOA-C02 中負責基礎設施佈建與維護的核心服務。Domain 3(部署、佈建與自動化)佔全卷 18%,而 Task Statement 3.1 明確要求考生「建立、管理並疑難排解 AWS CloudFormation」——注意有「疑難排解」這個動詞。SAA-C03 考的是架構設計時選用哪套 IaC 工具,SOA-C02 考的是你面對一個卡在 UPDATE_ROLLBACK_FAILED 的 Stack、一個在 200 個帳號中有 5 個失敗的 StackSet 操作、一個因 S3 bucket 非空而造成的 DELETE_FAILED,以及一個在 CloudFormation 之外被人改過而發生 Drift 的資源——你該怎麼把它修好。這門考試測的是修復 CloudFormation,而非設計 IaC 架構。
本指南從 SysOps 視角走過 CloudFormation 全流程:完整的 Stack 生命週期與你可能在凌晨三點看到的每個狀態碼、作為生產安全網的 Change Set、Drift Detection 與補救方式、四種 DeletionPolicy 值以及 UpdateReplacePolicy 的差異、阻止有狀態資源遭到意外更新的 Stack Policy、在部署期間監控 CloudWatch alarms 的 Rollback Trigger、self-managed 與 service-managed 模式下的 StackSets、以及在整個組織中自動部署到新帳號——還有 SOA-C02 反覆出現的場景:透過 ContinueUpdateRollback 還原 UPDATE_ROLLBACK_FAILED、StackSet 失敗容忍設定、1 小時的 Stack 建立逾時,以及會讓考生措手不及的 Parameter Store 整合。
為什麼 CloudFormation 是 SOA-C02 Domain 3 的核心
官方 SOA-C02 Exam Guide v2.3 在 Task Statement 3.1 下列出五項技能,CloudFormation 直接出現在其中三項:「建立、管理並疑難排解 AWS CloudFormation」;「跨多個 AWS region 和帳號佈建資源(例如 AWS RAM、CloudFormation StackSets、IAM 跨帳號角色)」;以及「識別並補救部署問題(例如 service quotas、subnet 大小、CloudFormation 錯誤、權限)」。Task Statement 3.2 則在上面疊加了自動化層——Systems Manager 和 CloudFormation 是考試指南中唯一以「自動化部署流程」為例點名的兩個自動化服務。
在 SysOps 層級,問題框架是運維導向的。SAA-C03 問「架構師應該為多帳號 Landing Zone 選擇哪套 IaC 工具?」SOA-C02 問「Stack 更新在 60% 處失敗,Stack 現在卡在 UPDATE_ROLLBACK_FAILED,三個資源卡在 UPDATE_FAILED,生產資料庫有 DeletionPolicy: Retain——下一步是什麼?」答案幾乎不是換一套 IaC 工具;而是帶著 ResourcesToSkip 清單呼叫 ContinueUpdateRollback。CloudFormation Stacks 和 StackSets 是所有 Domain 3 後續主題的插槽——AMI 生命週期與 Image Builder 流水線(3.1)產出 CloudFormation 在 launch template 中引用的 AMI;Systems Manager Automation(3.2)是 AWS 管理的 runbook 引擎,CloudFormation 可在 Stack 操作期間呼叫它,它也操作 Stack 部署的資源;排程任務(3.2)往往本身就是 CloudFormation custom resources 或 Stack 建立觸發器。
- Template:描述 AWS 資源預期狀態的 JSON 或 YAML 文件。Template 宣告
Parameters、Mappings、Conditions、Resources、Outputs和Transform。 - Stack:一份 template 的單一部署——CloudFormation 作為整體管理的單元。Stack 中的每個資源一起建立、更新和刪除。
- Change set:預覽 CloudFormation 在執行後將對 Stack 進行的所有變更。讓你在任何資源被動到之前先驗證哪些是替換、哪些是就地修改。
- Drift:Stack 預期設定(依 template)與資源實際設定(依 AWS API)之間的差異。由帶外編輯所造成。
- Rollback:
CREATE或UPDATE失敗時自動還原 Stack 變更。產生ROLLBACK_IN_PROGRESS、UPDATE_ROLLBACK_IN_PROGRESS等狀態,失敗時則為UPDATE_ROLLBACK_FAILED。 - DeletionPolicy:資源層級屬性,控制資源從 Stack 移除時的行為——
Delete(多數資源的預設值)、Retain、Snapshot(適用於有狀態服務)、或RetainExceptOnCreate。 - UpdateReplacePolicy:資源層級屬性,控制更新需要替換時舊資源的處置方式——值集合與
DeletionPolicy相同。 - Stack policy:附加到 Stack 的 JSON 政策,授予或拒絕對 Stack 內特定資源的更新權限——保護有狀態資源免於意外修改。
- Rollback trigger:在 Stack 建立或更新期間被引用的 CloudWatch alarm;若 alarm 在設定的 Monitoring Time 內觸發,CloudFormation 自動回滾。
- StackSet:讓你將單一 template 部署到許多帳號和許多 region 的容器,從管理員帳號集中管理。
- Stack instance:StackSet 在特定帳號-region 組合中建立的一個 Stack。一個 StackSet 在每個(帳號、region)對中有一個 Stack instance。
- Self-managed permissions:StackSet 模式,你需要在管理員和目標帳號中手動建立 IAM 角色。
- Service-managed permissions:StackSet 模式,AWS Organizations 自動建立並管理所需角色;支援自動部署到新帳號。
- 參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html
白話文解釋 CloudFormation Stacks and StackSets
CloudFormation 的術語比 Domain 3 任何其他主題都多。三個類比能讓這些概念牢牢記住。
類比一:建築師事務所的設計圖與建管局
CloudFormation 的 template 就像建築師事務所畫的設計圖——標明每道牆、每條管線、每個插座,但什麼都還沒蓋。Stack 是建管局依據那張設計圖核准完工的建築物;建管局記錄哪棟建物存在、哪張設計圖生出了它。Change set 是承包商在動工前張貼在大門的施工變更申請書——鄰居和屋主看到「我們要拆承重牆(代表整棟重建)並加蓋一間新浴室(代表小幅就地改動)」,在任何不可逆工程開始前決定核准或否決。Drift Detection 是帶著原始設計圖逐一走訪每個房間的建築稽查員,他寫下「廚房多了一道設計圖上從未出現的牆——有人沒申請就自己砌了」。資源上的 DeletionPolicy: Retain 是地契裡的不得拆除條款——就算其餘建物全部拆光,地基依然保留。Stack policy 是貼在機房門口的作業規範:「即使架構師的設計圖這樣寫,未經特別申請不得修改資料庫。」StackSet 是連鎖加盟建商——同一張設計圖在全台 50 個縣市各蓋一棟店面,全由總部統一管理。Service-managed StackSets 是AWS Organizations 的都市計畫局自動替每個加盟縣市核發建照;self-managed StackSets 是每個縣市的地方首長必須各自手動簽發建照。
類比二:夜市小吃攤的食譜與出餐流程
Template 是夜市攤位的食譜本——食材、步驟、火候、擺盤全寫清楚。Stack 是依據這本食譜實際端出去的一盤菜;每盤菜都可以追溯到哪個版本的食譜。Parameters 是客人點餐時的客製需求(「豬血糕不加香菜」)——食譜開放這些選項讓客人自選。Outputs 是前一道菜傳給下一個攤位的備料交接便條(「這鍋高湯的 ARN 交給滷肉飯攤」)。透過 Outputs 和 Fn::ImportValue 進行的 Cross-Stack References 就是湯品攤把高湯鍋傳給滷味攤——湯品食譜 Outputs 高湯 ARN,滷味食譜 ImportValue 拿去用。Change set 是老闆在出餐前讓副廚先試吃一小份——試吃OK才上給客人,不然整盤退回。以 CloudWatch alarm 為核心的 Rollback trigger 是廚房煙霧偵測器——備料途中警報響,整道菜全數丟棄、菜單回到上一版。Monitoring Time 的 30 分鐘就是老闆盯著出餐後的客人反應整整半小時;若客人在 30 分鐘內退菜,廚房就回滾這次的食譜調整。
類比三:連鎖圖書館的館藏系統與跨館借調
Stack 是圖書館架上的一本書——被借出、被追蹤、作為整體管理。Template 是出版社的原稿。Drift 是館員在書頁空白處寫了眉批;原稿和架上的書不再一致,若下次重印沒有把眉批正式納入原稿,眉批就消失了。StackSet 是跨分館聯合館藏系統:總館把同一本書推送到全市每個分館。Stack instance 是某個分館那一本書的館藏副本。StackSet 操作的 Concurrent regions 就是同時向幾個分館發送新書的貨車數量——一次向太多分館配送,搬運站就會塞車;預設一次只配一個 region,有其道理。Failure tolerance 是有幾個分館可以拒收,總館才會喊停整批配送——若 5 個分館以消防法規為由退貨,要繼續送剩下 195 間分館,還是暫停這次推廣活動?
對 SOA-C02 而言,當考題同時涉及 Change Set、Drift Detection 和 DeletionPolicy 時,建管局類比最有用——「建築物已不符設計圖」直接點破 Drift 的意義。當考題涉及跨帳號的 StackSets 時,跨分館圖書館類比能清楚說明 concurrent regions 和 failure tolerance 為何是各自獨立的設定旋鈕。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html
CloudFormation Stack 生命週期:凌晨三點你會看到的狀態碼
在疑難排解有意義之前,你需要對 Stack 生命週期和 CloudFormation 可能顯示的每個狀態碼有清晰的心智模型。
建立生命週期
CREATE 操作成功時依序經過 CREATE_IN_PROGRESS → CREATE_COMPLETE。失敗時預設行為是自動回滾:CREATE_IN_PROGRESS → ROLLBACK_IN_PROGRESS → ROLLBACK_COMPLETE。ROLLBACK_COMPLETE 狀態是終態——你無法更新或從中還原。唯一有效的動作是刪除 Stack 再重新建立。
若以 --disable-rollback(API 中的 OnFailure: DO_NOTHING 選項)停用自動回滾,Stack 會停留在 CREATE_FAILED,讓你在刪除前檢查部分建立的資源和錯誤軌跡。這是用於難以重現失敗的 template 的除錯模式,絕非生產設定。
更新生命週期
成功的 UPDATE 經過 UPDATE_IN_PROGRESS → UPDATE_COMPLETE_CLEANUP_IN_PROGRESS → UPDATE_COMPLETE。清理階段刪除更新所替換的資源——例如,若某個 instance 以新 AMI 重建,舊 instance 只在清理階段才會終止。CloudFormation 只在 UPDATE_COMPLETE 之後才再次允許更新 Stack。
失敗時,自動回滾啟動:UPDATE_IN_PROGRESS → UPDATE_ROLLBACK_IN_PROGRESS → UPDATE_ROLLBACK_COMPLETE。原始狀態恢復,Stack 再次可更新。到目前為止都還好。
危險的狀態是 UPDATE_ROLLBACK_FAILED。這意味著回滾本身遇到錯誤——例如,某個資源無法恢復到先前的設定,因為某個外部相依項目已被刪除,或者 IAM 角色在回滾途中被移除。Stack 現在卡住了。還原 API 是 ContinueUpdateRollback,可選擇帶上 ResourcesToSkip 參數,列出你希望 CloudFormation 在重試回滾時跳過的資源邏輯 ID。跳過的資源在 Stack 中繼資料中被標記為 UPDATE_COMPLETE,即使它們可能與 template 不符——這是刻意的運維覆蓋。
刪除生命週期
DELETE 操作經過 DELETE_IN_PROGRESS → DELETE_COMPLETE。失敗時,Stack 進入 DELETE_FAILED。常見原因是 S3 bucket 非空(S3 bucket 在刪除前必須是空的)、Retain 的資源阻礙刪除順序、IAM 權限缺口,或 EC2 instance 的終止保護。還原方式是修復根本原因後重試 DELETE,可選擇帶上 RetainResources 跳過有問題的邏輯 ID。
狀態快速參考
| 狀態 | 含義 | 還原方式 |
|---|---|---|
CREATE_COMPLETE |
Stack 建立成功 | 可更新 |
CREATE_FAILED |
停用回滾後的建立失敗 | 檢查後刪除 |
ROLLBACK_COMPLETE |
建立失敗後自動回滾——終態 | 刪除後重新建立 |
UPDATE_COMPLETE |
更新成功 | 可更新 |
UPDATE_ROLLBACK_COMPLETE |
更新失敗,原始狀態已還原 | 可更新 |
UPDATE_ROLLBACK_FAILED |
回滾本身失敗 | ContinueUpdateRollback API |
DELETE_FAILED |
刪除遇到錯誤 | 修復根本原因,重試刪除(可選 RetainResources) |
REVIEW_IN_PROGRESS |
Stack 由 Change Set 建立,Change Set 尚未執行 | 執行或刪除 Change Set |
許多考生混淆這兩者。ROLLBACK_COMPLETE 來自失敗的 CREATE:Stack 從未成功過,無法更新或進一步回滾;唯一的出路是 DELETE 後重建。UPDATE_ROLLBACK_FAILED 來自 UPDATE 期間失敗的回滾:Stack 先前是健康的,更新部分成功,回滾部分失敗,還原方式是 ContinueUpdateRollback——可選帶上 ResourcesToSkip。在 SOA-C02 上混淆兩者會白白丟掉送分題。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-rollback.html
Stack 建立逾時:隱藏的 1 小時預設值
SOA-C02 的一個微妙陷阱:CloudFormation 的 WaitCondition 和 CreationPolicy 預設每個資源逾時為 12 小時,但 Stack 本身沒有硬性的建立逾時——然而,各個操作和許多資源類型在內部各自執行自己的逾時。SOA-C02 最相關的數字是 CreationPolicy.ResourceSignal.Timeout,對於需要 user-data 發出 cfn-signal 的 instance 和 Auto Scaling group,預設值為 1 小時(PT1H)。
如果啟動中的 EC2 instance 的 user-data 未在逾時視窗內呼叫 cfn-signal --success,Stack 建立會失敗並顯示 Failed to receive 1 resource signal(s) within the specified duration。修復方式之一:
- 讓 user-data 執行得更快。
- 增加
CreationPolicy.ResourceSignal.Timeout值(PT2H、PT4H等)。 - 將相依項目預先封裝到黃金 AMI 中,讓 user-data 不需要現場安裝。
- 從
cfn-signal改用輪詢應用程式就緒狀態的 custom resource。
- 預設
CreationPolicy.ResourceSignal.Timeout:1 小時(PT1H)。 - 最大
CreationPolicy.ResourceSignal.Timeout:12 小時(PT12H)。 - 預設
WaitCondition逾時:12 小時。 - Change set 保留:Change set 可無限期保留直到執行或刪除;沒有自動過期,但舊 Change set 在 Stack 發生變動後會變成過時,AWS 建議用完後刪除。
- 預設 StackSet 操作並發:一次 1 個 region(預設依序部署;可用
RegionConcurrencyType: PARALLEL提高)。 - 預設 StackSet 帳號並發:
MaxConcurrentCount = 1或MaxConcurrentPercentage = 0(除非明確調高,否則等同於序列)。 - 預設 StackSet 失敗容忍:
FailureToleranceCount = 0——第一個失敗就停止操作。 - 單一 template 的最大
Resources數:500(從舊上限 200 提升至 500)。 - 最大 template body 大小:透過 S3 上傳為 1 MB,透過 API 直接傳遞為 51,200 bytes。
- 每個 template 最大
Parameters數:200。 - 每個 template 最大
Outputs數:200。 - 每個 template 最大
Mappings數:200。 - 參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html
常見部署錯誤與診斷方法
CloudFormation 將錯誤以 Stack 事件的形式呈現在主控台(以及透過 DescribeStackEvents API)。每個事件都有邏輯 ID、資源類型、狀態和狀態原因——狀態原因是你主要的診斷輸入。
IAM 權限不足
最常見的部署失敗。CloudFormation 使用以下兩者之一執行操作:
- 呼叫 Stack 操作的使用者/角色——其權限必須涵蓋 template 所涉及的每個資源動作。
- 在 Stack 建立時指定的 CloudFormation service role——CloudFormation 使用 service role 建立資源,將 Stack 執行權限與呼叫者權限解耦。
如果 Stack 事件顯示 User: arn:aws:iam::123:role/X is not authorized to perform: ec2:RunInstances,表示你有 IAM 缺口。修復角色政策或附加擁有更廣泛權限的 service role。
Service quota 超限
如果 Stack 嘗試在 quota 為 20 的 region 中建立第 21 個 VPC,資源事件會顯示 The maximum number of VPCs has been reached。解法:透過 Service Quotas 申請 quota 提升、清理閒置資源,或將 Stack 拆分到多個帳號。Domain 3.1 明確將「service quotas」列為部署問題類別。
屬性值無效
Template 引用了在該 region 不存在的 AMI ID、在 AZ 中無法使用的 instance 類型,或尚未驗證的 SSL 憑證。錯誤通常很清楚:The image id '[ami-xxxxx]' does not exist。解法:用 AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> 類型的 Parameters 將 AMI ID 參數化,讓 CloudFormation 在部署時從 SSM Parameter Store 讀取正確的 AMI。
相依性循環
若兩個資源透過 Ref 或 GetAtt 互相引用,CloudFormation 無法決定先建立哪個。錯誤為 Circular dependency between resources: [A, B]。解法:只在一個方向使用 DependsOn 打破循環,或引入第三個資源(通常是 SSM Parameter 或 Lambda 支援的 custom resource)來仲介值的傳遞。
Subnet 大小
Template 嘗試在只有 32 個可用 IP 的 subnet 中啟動 50 個 instance。錯誤:There are not enough free addresses in subnet。解法:透過重新撰寫 template 擴大 subnet,或拆分到其他 AZ 的額外 subnet。考試指南明確將「subnet sizing」列為部署問題。
SOA-C02 常見的干擾選項:template 硬寫了一個 AMI ID,Stack 在 us-east-1 正常運作,但在 eu-west-1 失敗。考生可能會選「使用 Mappings」——可行但繁瑣。較乾淨的 SOA-C02 答案是 AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>——CloudFormation 在 Stack 建立時從 SSM Parameter Store 讀取 AMI ID,支援 AWS 管理的 /aws/service/ami-amazon-linux-latest/... 參數,並自動適應每個 region。Mappings 是舊式答案;SSM Parameter Store 類型是現代答案。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html
Change Set:在執行前預覽 Stack 更新
Change set 是 CloudFormation 將對現有 Stack 進行的每個變更的預覽——每個將被新增、就地修改、替換(即銷毀再重建)或移除的資源。Change set 是防止意外資料遺失的生產安全網。
Change set 存在的原因
直接 Stack 更新(UpdateStack API)立即執行。如果更新更改了有狀態資源上需要替換的屬性——例如修改 RDS instance 的 DBSubnetGroupName——CloudFormation 會建立新的 RDS instance 並刪除舊的。**除非你用 DeletionPolicy: Snapshot 或 UpdateReplacePolicy: Snapshot 保護了該資源,否則舊資料就消失了。**因此,一次直接更新可以用一行 CLI 指令清空資料庫。
Change set 強制加入一個審查步驟。同樣更新的 Change set 輸出會顯示 RDSInstance: REPLACEMENT_REQUIRED——操作者在任何資源被動到之前就看到警告,可以取消變更、編輯 template,或有意識地繼續。
建立與執行 Change set
aws cloudformation create-change-set \
--stack-name web-prod \
--template-body file://template.yaml \
--change-set-name pr-432-update \
--change-set-type UPDATE
CloudFormation 在 CREATE_PENDING → CREATE_COMPLETE 中產生 Change set。用 describe-change-set 檢查。每個變更被分類為:
- Add — 將建立新資源。
- Modify — 現有資源將就地修改(無替換)。
- Modify with
RequiresRecreation: Always— 資源將被替換;舊資源被銷毀。 - Modify with
RequiresRecreation: Conditionally— 是否替換取決於額外的情境。 - Remove — 資源將被刪除。
準備好後執行:
aws cloudformation execute-change-set --change-set-name pr-432-update --stack-name web-prod
如果發現 Change set 有誤,在不執行的情況下刪除:aws cloudformation delete-change-set ...。刪除 Change set 對線上 Stack 沒有任何影響。
用於新 Stack 的 Change set
Change set 也適用於新 Stack 的建立:傳入 --change-set-type CREATE。Stack 以 REVIEW_IN_PROGRESS 狀態建立,只有在執行 Change set 後 Stack 才會真正生效。這對於有條件資源的 template 很有用——操作者可以在提交之前驗證將建立哪些資源。
SOA-C02 在任何「團隊意外替換了生產資料庫」的情境中都偏好 Change set 作為答案。修復是流程面的——在部署流水線中強制要求使用 Change set,永遠不要對生產 Stack 直接呼叫 UpdateStack。結合 DeletionPolicy: Snapshot 和一個拒絕對資料庫進行 Update:* 的 Stack policy,資料庫就有了三重防護,幾乎不可能被意外摧毀。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-changesets.html
Drift Detection:當現實偏離 Template
Drift 是 Stack 預期狀態(依最後一次成功操作時的 template)與資源實際狀態(依當前 AWS API)之間的差異。當有人透過主控台、CLI 或其他工具修改了 Stack 管理的資源——帶外編輯——就會發生 Drift,而下次 CloudFormation 更新會靜默地覆蓋這些改動。
偵測 Drift
Drift Detection 按需執行:
aws cloudformation detect-stack-drift --stack-name web-prod
# 回傳一個 StackDriftDetectionId
aws cloudformation describe-stack-resource-drifts --stack-name web-prod
每個資源被報告為 IN_SYNC、MODIFIED、DELETED 或 NOT_CHECKED(該資源類型不支援 Drift Detection)。對於修改過的資源,CloudFormation 列出每個不同的屬性,包括預期值和實際值。
Drift Detection 是唯讀的——它不會改變任何東西。操作者決定補救方式。
補救策略
三種策略,依情況選擇:
- 更新 template 以符合現實。 如果帶外變更是刻意的(例如,資安團隊手動收緊了 security group),修改 template,提交到 Git,並執行 Stack 更新。下次 Stack 更新不會覆蓋該變更,因為 template 現在已與之相符。
- 重新套用 template 以覆蓋現實。 如果帶外變更是意外或未授權的,在不更改 template 的情況下執行 Stack 更新——CloudFormation 偵測到差異並將資源還原為 template 的定義。
- 使用 AWS Config rules 持續標記 Drift。 託管 Config rule
cloudformation-stack-drift-detection-check按排程執行 Drift Detection 並回報不合規的 Stack。結合 EventBridge → SNS,Drift 一出現就立刻浮現,而不是幾週後才發現。
Drift Detection 無法幫助的情況
某些資源類型不支援 Drift Detection,部分受支援類型的某些屬性也不在 Drift 比較範圍內。CloudFormation 使用者指南列出了哪些資源類型受支援;常見的託管服務如 RDS、EC2 instances、IAM 角色、S3 bucket 和 Lambda functions 都受支援,而某些自訂或老舊資源類型則不受支援。
在 SOA-C02 中,「資安團隊在 50 個 Stack 中偵測到 Drift 資源」對應的是組織範圍的模式:透過 Config Aggregator 將 AWS Config rule cloudformation-stack-drift-detection-check 部署到每個帳號、以 Config 合規變更事件觸發 EventBridge rules,並透過 Systems Manager Automation 進行通知或自動補救。考試偏好這種端到端的流水線答案,而非一次性的 detect-stack-drift CLI 呼叫。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-drift.html
DeletionPolicy:Retain、Delete、Snapshot、RetainExceptOnCreate
DeletionPolicy 資源屬性控制資源從 Stack 移除時的行為——無論是 Stack 被刪除還是資源從 template 中移除。四個值:
Delete(多數資源的預設值)——Stack 被刪除或資源從 template 中移除時,資源被銷毀。Retain——Stack 被刪除或移除時,資源被保留;它成為孤兒(不再被任何 Stack 管理),但繼續存在並產生費用。Snapshot——支援有狀態資源(RDS DB instances、RDS DB clusters、EBS volumes、ElastiCache、Neptune、Redshift、FSx);CloudFormation 在刪除資源之前建立最終快照。還原需要從快照手動恢復。RetainExceptOnCreate——刪除時資源被保留,除了在失敗的建立操作期間。適用於應該在正常刪除中存活但不應在失敗的初始部署後堆積的資源。
多數資源的預設值是 Delete,但少數有狀態類型預設值不同或建議明確設定政策。請始終對有狀態資源明確設定 DeletionPolicy——RDS、EBS、你不想失去的 S3 bucket、KMS 金鑰、你希望在 Stack 之後繼續存在的 IAM 資源。
常見組合
- RDS 資料庫:
DeletionPolicy: Snapshot, UpdateReplacePolicy: Snapshot——在 Stack 刪除或替換時建立最終快照。 - 存放生產資料的 S3 bucket:
DeletionPolicy: Retain, UpdateReplacePolicy: Retain——bucket 在 Stack 刪除後繼續存在;資料安全。 - KMS CMK:
DeletionPolicy: Retain——KMS 金鑰無論如何都無法立即刪除(它們會進入 7 到 30 天的待刪除視窗),而且你幾乎永遠不會想失去一把被其他地方的密文引用的金鑰。 - Auto Scaling launch template:
DeletionPolicy: Delete(預設)——launch template 不是有狀態的;可以安全地重建。
DeletionPolicy 在 Stack 刪除時 vs 資源移除時
DeletionPolicy 在兩種情況下均適用:
- 透過
DeleteStack刪除整個 Stack 時,每個資源的DeletionPolicy都會被遵守。 - 從 template 中移除單一資源(template 不再宣告它)時,下次 Stack 更新會套用該資源的
DeletionPolicy。
DeletionPolicy 不適用於更新替換
如果就地更新不可能且 CloudFormation 必須替換資源,DeletionPolicy 不是保護舊副本的屬性——那是 UpdateReplacePolicy 的工作(下一節)。這是 SOA-C02 的常見陷阱。
一個常見的錯誤模式:考生對 RDS instance 加了 DeletionPolicy: Snapshot,然後以為資料庫在所有情況下都安全了。其實不然。如果未來的 template 變更需要替換(例如以觸發替換的方式更改 DB 引擎版本),DeletionPolicy 毫無關係——UpdateReplacePolicy 才決定被替換的資源是否建立快照。防禦性組合是在每個有狀態資源上同時設定 DeletionPolicy: Snapshot 和 UpdateReplacePolicy: Snapshot。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html
UpdateReplacePolicy:防止更新觸發的替換
UpdateReplacePolicy 資源屬性控制更新操作以新副本替換資源時,原始資源的處置方式。值集合與 DeletionPolicy 相同——Delete(預設)、Retain、Snapshot、RetainExceptOnCreate。
CloudFormation 何時替換?
某些屬性無法在現有資源上修改。範例:
- 在某些情況下,更改 RDS 的
DBInstanceClass會觸發就地修改,但更改DBSubnetGroupName需要替換。 - 更改 RDS 的
Engine強制替換。 - 更改 EC2 instance 的
KeyName強制替換。 - 更改 AZ 固定資源的
AvailabilityZone強制替換。 - 更改資源的邏輯 ID 在概念上相當於刪除 + 建立——效果相同。
Change set 為每個屬性變更標記 RequiresRecreation: Always | Conditionally | Never。任何 Always 都觸發替換,而 UpdateReplacePolicy 決定舊副本的命運。
為什麼 UpdateReplacePolicy: Snapshot 存在
想像一個 RDS instance,有人更改了一個需要替換的屬性。沒有 UpdateReplacePolicy,預設是 Delete——舊資料庫在清理期間被銷毀,沒有快照。新資料庫是空的。生產資料:消失了。有了 UpdateReplacePolicy: Snapshot,CloudFormation 在刪除舊資料庫之前建立快照,保留緊急還原路徑。
生產 template 應該對每個有狀態資源明確設定兩個屬性。RDS、EBS、ElastiCache、Redshift、Neptune、FSx 的防禦慣例:
ProductionDatabase:
Type: AWS::RDS::DBInstance
DeletionPolicy: Snapshot
UpdateReplacePolicy: Snapshot
Properties: ...
只設其中一個留有漏洞。SOA-C02 明確測試這個組合。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html ::
Stack Policy:阻止對有狀態資源的意外更新
Stack policy 是附加到 Stack 的 JSON IAM 風格政策,控制在 Stack 更新期間哪些資源可以被修改。無論誰觸發更新,CloudFormation 都在伺服器端強制執行此政策。
Stack policy 結構
Stack policy 有 Effect、Action、Principal、Resource 和可選的 Condition。Actions 限於 Update:*、Update:Modify、Update:Replace、Update:Delete。Principal 始終是 *。Resources 以 LogicalResourceId/* 模式引用。
預設 Stack policy(未設定時):Allow Update:* on *——每個資源都可更新。
一個常見的防禦政策:
{
"Statement": [
{ "Effect": "Allow", "Principal": "*", "Action": "Update:*", "Resource": "*" },
{ "Effect": "Deny", "Principal": "*", "Action": "Update:*", "Resource": "LogicalResourceId/ProductionDatabase" }
]
}
這允許更新除生產資料庫以外的所有資源。任何影響 ProductionDatabase 的更新在 Stack 更新時會被拒絕。
單次更新的覆蓋
要刻意更新受保護的資源,你需要傳遞一個臨時覆蓋 Stack policy(StackPolicyDuringUpdateBody),它只適用於那次單一更新。這強制了刻意的操作者決策,而不是僅依賴持久的 Stack policy。
Stack policy vs IAM policy
| 機制 | 範圍 | 範例用途 |
|---|---|---|
| Stack policy | 每個 Stack,控制 Stack 內哪些資源可以被更新 | 阻止 ProductionDatabase 邏輯資源的更新 |
| IAM policy | 每個身份,控制誰可以完全呼叫 CloudFormation API | 只有 DevOps 角色可以呼叫 UpdateStack |
| Service Control Policy (SCP) | 每個組織-OU,拒絕生產 OU 中的 CloudFormation 操作 | 阻止生產帳號中任何角色執行 DeleteStack |
| Stack 的 service role | 每個 Stack,CloudFormation 本身可以建立哪些 AWS 資源 | 限制失控 template 的爆炸半徑 |
這四種機制可以組合使用。穩健的生產設置使用全部四種——Stack policy、IAM、SCP 和有範圍的 service role。
SOA-C02 的微妙陷阱:Stack policy 涵蓋 Update:* 操作。它們不防止 Stack 刪除。DeleteStack API 呼叫遵守每個資源上的 DeletionPolicy,但完全忽略 Stack policy。要防止 Stack 刪除,使用:(a) IAM 在該 Stack ARN 上拒絕 cloudformation:DeleteStack,(b) 在 Stack 上啟用termination protection(UpdateTerminationProtection),或 (c) OU 層級的 SCP。深度防禦意味著結合 Stack policy(對抗更新)、termination protection(對抗刪除)和不可恢復資源上的 DeletionPolicy: Retain。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html
Rollback Trigger 與 Monitoring Time
CloudFormation 可以在建立或更新操作期間監控 Stack 的 CloudWatch alarms,並在任何 alarm 觸發時自動回滾。這就是 Rollback Trigger 加上 Monitoring Time。
Rollback Trigger 的運作方式
你為每個 Stack 操作設定最多 5 個 Rollback Trigger,每個指向一個 CloudWatch alarm ARN。在操作期間以及操作完成後的額外 Monitoring Time(0 到 180 分鐘)內,CloudFormation 輪詢這些 alarm。如果任何觸發器轉換為 ALARM,CloudFormation 自動將 Stack 回滾到先前的狀態。
這是 CloudFormation 最接近原生金絲雀部署的功能——你可以更新一個運行新版本應用程式的 Stack,對應用程式的 5xx 錯誤率 alarm 設定 Rollback Trigger,Monitoring Time 30 分鐘,完成後 30 分鐘內任何錯誤率飆升都會自動還原部署。
透過 CLI 設定
aws cloudformation update-stack \
--stack-name web-prod \
--template-body file://template-v2.yaml \
--rollback-configuration '{
"RollbackTriggers": [
{ "Arn": "arn:aws:cloudwatch:us-east-1:123:alarm:5xx-error-rate", "Type": "AWS::CloudWatch::Alarm" }
],
"MonitoringTimeInMinutes": 30
}'
Monitoring Time
監控視窗從 Stack 達到 UPDATE_COMPLETE(或 CREATE_COMPLETE)時開始,持續設定的分鐘數。在此視窗期間,Stack 被視為「觀察中」——alarm 觸發會導致回滾。視窗結束後,alarm 對 Stack 沒有影響。
MonitoringTimeInMinutes: 0 表示監控視窗為零(alarm 只在操作本身期間被檢查,而非之後)。180 是最大值。
Rollback Trigger vs 藍綠部署
Rollback Trigger 處理的是運行中的 Stack 本身作為部署目標的就地部署。對於完整的藍綠部署——兩個平行 Stack,透過 Route 53 加權記錄或 ALB target group 切換來轉移流量——CloudFormation 沒有原生原語;你需要手動用兩個 Stack 加上一個自動化 runbook 來組合。Rollback Trigger 涵蓋就地情況;藍綠是以 CloudFormation 作為組件的更高層級模式。
當考題問「團隊需要部署新應用程式版本,並在 5xx 錯誤在 30 分鐘內飆升時自動還原」——答案是帶 Monitoring Time 的 Rollback Trigger。CodeDeploy 超出 SOA-C02 範圍;考試認可的自動回滾工具是 CloudFormation Rollback Trigger。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-rollback-triggers.html
CloudFormation StackSets:多帳號、多 Region 部署
StackSet 是一個容器,讓單一 template 可以作為 stack instances 跨許多帳號和許多 region 部署,全部從管理員帳號集中管理。這是 SOA-C02「將此基準部署到組織中每個帳號」的標準答案——護欄、日誌設定、IAM 角色、資安工具。
StackSets 術語
- Administrator account:持有 StackSet 定義並從中啟動操作的帳號。
- Target account:每個接收 stack instance 的帳號。
- Stack instance:在(目標帳號、region)組合中部署的一個 Stack。一個 StackSet 包含 50 個帳號 × 4 個 region,共 200 個 stack instances。
- Operation:一個 create-stack-instances、update-stack-set 或 delete-stack-instances 動作——跨設定的帳號-region 矩陣執行。
Self-managed permissions vs service-managed permissions
兩種模式在跨帳號信任的建立方式上不同:
Self-managed permissions
- 管理員帳號持有
AWSCloudFormationStackSetAdministrationRole。 - 每個目標帳號持有一個
AWSCloudFormationStackSetExecutionRole,其信任政策允許管理員角色假扮它。 - 操作者必須在 StackSet 可以部署之前手動建立兩個角色(CloudFormation 提供 template)。
- 不需要 AWS Organizations——適合尚未採用 Organizations 的組織。
Service-managed permissions
- 需要啟用所有功能的 AWS Organizations(不僅是合併帳單)。
- 必須在組織中為 CloudFormation 啟用受信任存取。
- AWS Organizations 自動建立並管理必要的 IAM 角色。
- 支援自動部署:新帳號加入組織單位時,StackSet 自動將 Stack 部署到新帳號——這對 landing zone 至關重要。
- 支援部署到整個 OU,而非枚舉帳號 ID。
| 功能 | Self-managed | Service-managed |
|---|---|---|
| 需要 Organizations | 否 | 是(所有功能) |
| IAM 角色 | 手動 | 自動建立 |
| 依 OU 定向 | 否(僅帳號 ID) | 是 |
| 自動部署到新帳號 | 否 | 是 |
| 使用場景 | 無 Organizations 或特定帳號選擇 | 全組織基準、Landing Zone |
StackSet 操作的三個關鍵旋鈕
每個 SOA-C02 考生必須知道的三個旋鈕:
MaxConcurrentCount/MaxConcurrentPercentage:在一個 region 內同時部署到幾個帳號。預設 1(序列)。較高的值加快部署但增加 template 有 bug 時的爆炸半徑。FailureToleranceCount/FailureTolerancePercentage:在停止操作前可容忍幾個帳號失敗。預設 0(第一個失敗就停止)。較高的值允許推出在隔離失敗後繼續。RegionConcurrencyType:SEQUENTIAL(預設——一次一個 region)或PARALLEL(所有 region 同時,快得多但風險更高)。對於 service-managed StackSets,還要設定RegionOrder以在序列模式下選擇部署順序。
典型的全組織推出使用 MaxConcurrentPercentage: 25, FailureTolerancePercentage: 5, RegionConcurrencyType: SEQUENTIAL——在一次一個 region 的情況下,同時部署到 25% 的帳號,容忍最多 5% 失敗後才停止。
Service-managed StackSets 中的帳號篩選
Service-managed StackSets 在定向 OU 時支援帳號篩選:
NONE(預設)——部署到 OU 中的每個帳號。INTERSECTION——只部署到同時在列表和 OU 中的帳號。DIFFERENCE——部署到 OU 中的每個帳號,除了列出的帳號。UNION——部署到 OU 中的每個帳號,加上任何額外列出的帳號。
常見的生產模式是使用 DIFFERENCE 排除幾個尚無法接受基準的老舊帳號。
- 預設
MaxConcurrentCount:1(region 內序列部署)。 - 預設
FailureToleranceCount:0(第一個失敗停止操作)。 - 預設
RegionConcurrencyType:SEQUENTIAL(一次一個 region)。 - 每個 StackSet 的最大 stack instances 數(service-managed):每個管理員帳號每個 region 2,000 個。
- 最大操作並行性:一次 100 個帳號(
MaxConcurrentCount上限)。 - 自動部署:僅在 service-managed 模式下可用。
- 在 Organizations 中為 CloudFormation 啟用受信任存取:在建立任何 service-managed StackSet 之前必須完成。
- 參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-concepts.html
每當 SOA-C02 情境描述「將 CloudWatch alarm 基準部署到組織中每個現有和未來的帳號」,標準答案是啟用自動部署的 service-managed StackSets,定向到根 OU 或基準 OU。只有當情境明確說「公司不使用 AWS Organizations」或「只部署到一個小的固定帳號清單」時,self-managed StackSets 才是正確答案。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-orgs-enable-trusted-access.html
Cross-Stack References、Nested Stacks 與跨帳號 Stack 資源
CloudFormation 提供三種組合機制;SOA-C02 期望你知道每種的適用時機。
Outputs 和 Fn::ImportValue(Cross-Stack References)
匯出 Stack 宣告一個帶有 Export: { Name: my-vpc-id } 的 Output。匯入 Stack 使用 Fn::ImportValue: my-vpc-id。Cross-Stack references 的特性:
- 僅限同帳號、同 region。 不支援跨帳號或跨 region。
- 鬆散耦合。 匯出 Stack 不知道誰匯入了它的 outputs。
- 黏性。 一旦某個值被另一個 Stack 匯入,你就無法刪除或修改該匯出,直到匯入 Stack 停止使用它。
對於單一帳號-region 內的共享基礎設施,使用 Cross-Stack references——從網路 Stack 匯出 VPC、subnet、security group,供每個工作負載 Stack 匯入。
Nested Stacks
Nested stack 是在另一個 Stack 內作為資源建立的 Stack。父 Stack 有一個類型為 AWS::CloudFormation::Stack 的資源,指向 S3 中子 template 的 URL。Nested stacks 的特性:
- 共享父 Stack 的生命週期。 更新父 Stack 會更新所有 nested 子 Stack。
- 緊密耦合。 適合可重用的 template 模組(例如,在許多父 template 中使用的「VPC 模組」)。
- 直接透過
Parameters和Outputs傳遞 父子之間的參數和輸出。
Nested stacks 適合可重用的內部模組;Cross-Stack references 適合獨立管理的共享資源。
跨帳號 / 跨 Region——使用 StackSets
CloudFormation 沒有原生的跨帳號或跨 region Stack reference。要跨帳號部署相關資源,你用 StackSets 組合(每個 template 一個 StackSet),並使用 IAM 跨帳號角色進行部署資源之間的執行時存取。
- 同帳號、同 region、共享基礎設施:
Outputs+Fn::ImportValue。 - 可重用 template 模組:Nested Stacks(
AWS::CloudFormation::Stack)。 - 多帳號、多 region 基準:StackSets。
- 現有資源的跨帳號資源共享(例如 Transit Gateway):AWS Resource Access Manager (RAM),從 CloudFormation 引用為
AWS::RAM::ResourceShare。
混淆這些是 SOA-C02 常見的干擾選項。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html
內建函數:CloudFormation 工具箱
**內建函數(Intrinsic functions)**是 template 的內建輔助工具。SOA-C02 中你會反覆看到以下幾個:
Ref——引用參數或另一個資源。對於大多數資源類型,Ref回傳邏輯 ID(對許多資源來說即實體名稱,例如AWS::S3::Bucket的 bucket 名稱)。Fn::GetAtt/!GetAtt——取得資源的特定屬性(!GetAtt MyInstance.PrivateIp)。Fn::Sub/!Sub——將變數替換到字串中(!Sub "arn:aws:s3:::${BucketName}/*")。Fn::Join/!Join——以分隔符號連接值。Fn::ImportValue/!ImportValue——從另一個 Stack 匯入已匯出的 output。Fn::FindInMap/!FindInMap——按鍵在Mappings表中查找值(!FindInMap [RegionMap, !Ref AWS::Region, AMI])。Fn::If/!If——根據Condition在值之間選擇。Fn::GetAZs——回傳 region 中的 AZ 列表。Fn::Cidr——計算 subnet 大小的 CIDR 區塊。Fn::Base64——編碼 user-data 腳本。- 偽參數(Pseudo parameters)——
AWS::Region、AWS::AccountId、AWS::StackName、AWS::Partition、AWS::URLSuffix。
考試很少測試詳細語法,但知道哪個函數適用於哪種用例(特別是 Sub vs Join 以及 Ref vs GetAtt)是合理的考點。
場景模式:Stack 卡在 UPDATE_ROLLBACK_FAILED
這是 SOA-C02 的標準疑難排解場景。操作手冊:
- 檢查 Stack 事件。
aws cloudformation describe-stack-events --stack-name <name>顯示失敗鏈。識別無法回滾的資源以及底層錯誤訊息——通常是以下之一:外部相依項目遺失、IAM 權限在回滾途中被移除、資源在回滾期間在 CloudFormation 之外被修改。 - 決定要跳過哪些資源。 對於每個卡住的資源,決定 (a) 你是否能修復根本原因(例如,重建已刪除的 IAM 角色、重新連接 Internet Gateway),或 (b) 你接受資源的當前狀態並告訴 CloudFormation 在重試時跳過它。跳過是不可逆的——無論實際狀態如何,資源都被標記為
UPDATE_COMPLETE,後續的協調是你的責任。 - 呼叫
ContinueUpdateRollback。aws cloudformation continue-update-rollback \ --stack-name web-prod \ --resources-to-skip ResourceA ResourceB - 驗證最終 Stack 狀態。 Stack 應該達到
UPDATE_ROLLBACK_COMPLETE。從這裡開始它又可以更新了。 - 協調任何跳過的資源。 如果你跳過了某個資源,請透過 Stack 更新或帶外修復跟進,使其與 template 重新對齊。
SOA-C02 干擾選項清單中頻繁出現的錯誤答案:「刪除 Stack 並重新建立」。這會摧毀整個 Stack 及其所有資源,包括健康的資源。始終先嘗試 ContinueUpdateRollback。
場景模式:StackSet 操作在 200 個帳號中有 5 個失敗
一個 StackSet 更新在 200 個帳號中啟動。在 5 個帳號中失敗。預設行為:FailureToleranceCount = 0 表示操作在第一次失敗時就停止。其他 199 個帳號處於混合狀態。
操作手冊:
- 檢查操作結果。
aws cloudformation list-stack-set-operation-results --stack-set-name X --operation-id Y顯示每個帳號的狀態。識別 5 個失敗帳號及每個帳號的錯誤訊息。 - 分類失敗原因。 常見原因:目標帳號中缺少 IAM 角色(self-managed 模式)、目標帳號中的資源 quota、目標帳號中未啟用的 region、帳號被停用。
- 修復或排除失敗帳號。 修復(申請 quota 提升、啟用 region、修復 IAM 信任)或在下次操作中使用帳號篩選排除它們。
- 以更高的失敗容忍重新執行操作。 設定
FailureTolerancePercentage: 10或更高,使少數落後帳號不會停止整個推出。 - 對於 service-managed StackSets,考慮自動部署重試。 之後加入 OU 的新帳號將觸發自動重新部署。
場景模式:非空 S3 Bucket 導致的 DELETE_FAILED
SOA-C02 的常見陷阱。Stack 包含一個 AWS::S3::Bucket 資源。Stack 刪除失敗,顯示 The bucket you tried to delete is not empty。CloudFormation 無法刪除非空的 S3 bucket。
操作手冊:
- 手動清空 bucket(或透過在刪除時執行的 Lambda 支援 custom resource)。
- 重試 Stack 刪除。 可選擇傳遞
--retain-resources MyBucket,如果你想保留 bucket——CloudFormation 將資源從 Stack 中移除但保留 bucket。 - 對於未來的 template,用在 Stack 刪除時清空 bucket 的 custom resource 包裝 bucket,或設定
DeletionPolicy: Retain讓 bucket 在 Stack 外繼續存在。
相關陷阱:Stack 包含帶有 DeletionPolicy: Retain 的 KMS CMK。Stack 成功刪除但留下孤立的 CMK(仍產生費用)。這對 Retain 來說是設計如此,但操作者必須記住在成本審查期間手動清理保留的資源。
常見陷阱:Stack 建立逾時 vs 資源訊號逾時
一個常見的混淆點。沒有你設定的單一「Stack 建立逾時」。相反地:
- 每個資源類型有其自己的服務端建立逾時(RDS instance 可能最多需要 1 小時,EKS cluster 更長等)。
- 帶有
CreationPolicy.ResourceSignal的資源(通常是 EC2 instances 和 ASG)在Timeout內等待 user-data 的cfn-signal --success(預設PT1H,最大PT12H)。 WaitCondition資源有自己的Timeout(預設PT12H)。
如果 Stack 看起來卡在 CREATE_IN_PROGRESS,原因通常是某個資源花費的時間比預期長,而非全域「Stack 逾時」。檢查 Stack 事件以找到緩慢的資源。
常見陷阱:Parameter Store 類型被低度使用
硬寫 AMI ID、instance 類型或特定環境值的 template 會產生每個 region 或每個環境的維護負擔。SOA-C02 的乾淨答案:
AWS::SSM::Parameter::Value<String>——在部署時從 SSM Parameter Store 讀取 String 參數。AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>——從 Parameter Store 讀取 AMI ID。AWS::SSM::Parameter::Value<List<String>>——讀取逗號分隔的列表。
結合 AWS 管理的 AMI 參數(/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64)和 AWS 管理的 ECS 最佳化參數,template 在不需要 Mappings 的情況下就能跨 region 移植。
常見陷阱:Stack Policy 阻止更新但不阻止刪除
如上所述,這是一個反覆出現的干擾選項。Stack policy 只涵蓋 Update:*。Termination protection 加上 cloudformation:DeleteStack 的 IAM 拒絕才是防止刪除的方式。
常見陷阱:StackSets 並發 Region 預設是序列
RegionConcurrencyType 預設為 SEQUENTIAL。考生可能假設 StackSets 預設並行部署到所有 region——它們不是。對於在 200 個帳號跨 4 個 region 的全組織推出,序列 region 部署可能需要數小時。當爆炸半徑可接受時,設定 RegionConcurrencyType: PARALLEL 以加快推出速度,或搭配 SEQUENTIAL 和明確的 RegionOrder 先部署到金絲雀 region。
SOA-C02 vs SAA-C03:運維視角的差異
SAA-C03 和 SOA-C02 都涉及 CloudFormation,但視角不同。
| 問題類型 | SAA-C03 視角 | SOA-C02 視角 |
|---|---|---|
| IaC 選擇 | 「架構師應該使用哪個服務跨帳號部署?」 | 「StackSet 在 5 個帳號失敗了——下一步是什麼?」 |
DeletionPolicy |
「哪個功能在 Stack 刪除後保留資料庫?」 | 「團隊在 Stack 更新時意外丟失資料——缺少哪個屬性組合?」 |
| Change Set | 「哪個功能預覽 Stack 變更?」 | 「團隊用 UpdateStack 替換了生產資料庫——需要什麼流程改變?」 |
| Drift | 很少測試 | 「如何在 50 個 Stack 中偵測並補救 Drift?」 |
| Rollback | 「為什麼要用 rollback?」 | 「Stack 卡在 UPDATE_ROLLBACK_FAILED——呼叫哪個 API?」 |
| Stack policy | 很少測試 | 「阻止 Stack 內對生產資料庫的意外更新。」 |
| StackSets self vs service-managed | 「哪種模式支援自動部署到新的組織帳號?」 | 「團隊使用 Organizations 並希望每個新帳號都能收到基準——如何設定。」 |
SAA 考生選擇 CloudFormation;SOA 考生在失敗條件下、跨多帳號和多 region 範圍中操作它。
考試信號:如何識別 Domain 3.1 的 CloudFormation 考題
SOA-C02 的 Domain 3.1 考題遵循可預測的模式。
- 「Stack 卡在 UPDATE_ROLLBACK_FAILED」 →
ContinueUpdateRollbackAPI,可選帶ResourcesToSkip。不要以刪除再重建作為第一個答案。 - 「Stack 刪除失敗」 → 最可能是非空 S3 bucket、retained 資源或 termination protection。清空 bucket / 修復相依性 / 停用保護,然後重試。可選在重試時使用
RetainResources。 - 「Stack 更新期間生產資料庫意外被替換」 → 流程缺口。在部署流水線中要求 Change Set,對有狀態資源設定
UpdateReplacePolicy: Snapshot,附加拒絕資料庫資源Update:*的 Stack policy。 - 「將基準部署到組織中的每個帳號」 → 啟用自動部署的 service-managed StackSets,定向到根 OU 或基準 OU。
- 「StackSet 中某些帳號失敗」 → 調整
FailureToleranceCount/FailureTolerancePercentage,修復根本原因,重試。 - 「Stack 管理資源的 Drift」 →
detect-stack-drift+ Config rulecloudformation-stack-drift-detection-check+ EventBridge → SSM Automation 補救。 - 「AMI ID 硬寫,在另一個 region 失敗」 → Parameter 類型
AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>配合 AWS 管理的 AMI 參數路徑。 - 「部署期間 5xx 錯誤飆升時自動回滾」 → Rollback Trigger 配合指向 CloudWatch alarm 的 Monitoring Time。
- 「Stack 建立在 EC2 instance 的 60 分鐘時掛起」 →
CreationPolicy.ResourceSignal.Timeout超時;user-data 沒有呼叫cfn-signal --success。修復 user-data 或提高逾時(最大 12 小時)。 - 「Stack 建立期間 IAM 權限不足」 → 授予呼叫者更多權限或使用範圍更廣的 CloudFormation service role。
Domain 3 佔全卷 18%,Task Statement 3.1 涵蓋 CloudFormation、AMI、Image Builder、多帳號/多 region 和部署場景。CloudFormation 本身是這些中最深入的,可能佔 6 到 9 道題。掌握 UPDATE_ROLLBACK_FAILED 還原、Change Set、Drift、Stack policy、DeletionPolicy / UpdateReplacePolicy 和 StackSets 設定是高槓桿的學習活動。參考:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html
決策矩陣 — 每個 SysOps 目標對應的 CloudFormation 工具
在考試期間使用此查詢表。
| 運維目標 | 主要工具 | 備註 |
|---|---|---|
| 在套用前預覽 Stack 變更 | Change set | 生產更新一律使用。 |
| 偵測帶外編輯 | Drift Detection + Config rule cloudformation-stack-drift-detection-check |
透過 Config aggregator 排程全組織執行。 |
| 保護有狀態資源免於刪除 | DeletionPolicy: Retain 或 Snapshot |
RDS/EBS 用 Snapshot;KMS/S3 用 Retain。 |
| 保護有狀態資源免於替換 | UpdateReplacePolicy: Retain 或 Snapshot |
與 DeletionPolicy 搭配使用。 |
| 阻止對 Stack 內特定資源的更新 | Stack policy | 附加到 Stack 的 JSON 政策。 |
| 防止 Stack 刪除 | Termination protection + IAM 拒絕 DeleteStack |
Stack policy 不阻止刪除。 |
| 部署期間 metric 突破時自動回滾 | Rollback Trigger + Monitoring Time | 最多 5 個 alarm,0 到 180 分鐘監控。 |
從 UPDATE_ROLLBACK_FAILED 還原 |
ContinueUpdateRollback API |
可選帶 ResourcesToSkip。 |
從 ROLLBACK_COMPLETE 還原 |
刪除 Stack 並重新建立 | 終態——無就地還原。 |
從 DELETE_FAILED 還原 |
修復根本原因 + 重試刪除並帶 RetainResources |
常見原因:非空 S3 bucket。 |
| 跨多個 region 部署 | StackSets 搭配 RegionConcurrencyType |
預設序列;設 PARALLEL 加快速度。 |
| 跨多個帳號部署 | StackSets——若有 Organizations 則用 service-managed | 否則用 self-managed。 |
| 自動部署到加入 OU 的新帳號 | Service-managed StackSet 搭配自動部署 | 需要 Organizations 所有功能 + 受信任存取。 |
| 容忍隔離的帳號失敗 | FailureToleranceCount / FailureTolerancePercentage |
預設 0——第一個失敗停止。 |
| 跨 region 移植的 AMI 引用 | AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> |
使用 AWS 管理的參數路徑。 |
| EC2 長時間首次啟動訊號 | CreationPolicy.ResourceSignal.Timeout |
預設 1 小時,最大 12 小時。 |
| 可重用 template 模組 | Nested Stacks(AWS::CloudFormation::Stack) |
與父 Stack 緊密耦合。 |
| 在獨立 Stack 間共享基礎設施 | Outputs + Fn::ImportValue |
僅限同帳號/region。 |
| 跨帳號資源共享 | AWS RAM(AWS::RAM::ResourceShare) |
從 CloudFormation 引用。 |
| 限制 CloudFormation 操作的爆炸半徑 | CloudFormation service role + IAM 範圍限制 | Service role 代表 CloudFormation 行動。 |
| 稽核 CloudFormation 操作 | CloudTrail 管理事件 | 每個 CFN API 呼叫都被記錄。 |
| 排程週期性 Stack 更新 | EventBridge rule → Lambda → CloudFormation API | CFN 沒有原生排程器。 |
常見陷阱回顧 — CloudFormation Stacks 與 StackSets
每次 SOA-C02 考試都會出現其中兩到三個干擾選項。
陷阱一:ROLLBACK_COMPLETE 可以還原
不能。來自失敗 CREATE 的 ROLLBACK_COMPLETE 是終態——刪除並重建。只有來自更新期間失敗回滾的 UPDATE_ROLLBACK_FAILED 才能透過 ContinueUpdateRollback 還原。
陷阱二:DeletionPolicy 單獨可防止更新替換
不能。在每個有狀態資源上與 UpdateReplacePolicy 搭配使用。
陷阱三:Stack policy 阻止 Stack 刪除
不能。使用 termination protection 加上 IAM 拒絕來達到此目的。
陷阱四:詳細監控觸發 CloudFormation 回滾
不會。Rollback Trigger 是在 Stack 操作上明確設定的 CloudWatch alarm ARN,而非隱式的詳細監控。
陷阱五:StackSets 預設並行部署到所有 region
不是。RegionConcurrencyType 預設為 SEQUENTIAL。明確設定 PARALLEL 以加快推出速度。
陷阱六:Self-managed StackSets 支援自動部署
不支援。部署到新組織帳號的自動部署需要 service-managed permissions 加上 AWS Organizations 所有功能。
陷阱七:硬寫 AMI ID 可以接受
不行。使用 AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> 搭配 AWS 管理的參數路徑以實現 region 移植性。
陷阱八:刪除再重建是卡住 Stack 的正確答案
這是最後手段。始終先嘗試 ContinueUpdateRollback;考慮在刪除時使用 RetainResources;只有在這些都失敗時才刪除重建。
陷阱九:Cross-Stack References 可以跨帳號
不行。Fn::ImportValue 只在同帳號和 region 內有效。跨帳號需要 StackSets 或 AWS RAM。
陷阱十:CloudFormation 有全域 Stack 逾時
沒有。每個資源有其自己的服務端逾時;CreationPolicy.ResourceSignal.Timeout 對資源訊號資源預設為 1 小時。
陷阱十一:透過 template 清空 S3 Bucket
CloudFormation 無法清空 bucket。使用在刪除時清空的 Lambda 支援 custom resource,或在 Stack 刪除前手動清空,或對 bucket 設定 DeletionPolicy: Retain。
陷阱十二:Service quota 只在部署時檢查
它們在建立時逐資源檢查。更高層級的 quota(每個 region 的最大 stack 數、每個 template 的最大資源數)也會被強制執行。透過 Service Quotas + 在 80% 時觸發的 CloudWatch alarm 實現 quota 可見性。
FAQ — CloudFormation Stacks 與 StackSets
Q1:Stack 卡在 UPDATE_ROLLBACK_FAILED,我應該刪除它嗎?
不——至少不要先這樣做。還原 API 是 ContinueUpdateRollback,可選帶 ResourcesToSkip 列出無法回滾的邏輯 ID。檢查 Stack 事件以找出哪些資源失敗及其原因。如果根本原因可以修復(例如,重建已刪除的 IAM 角色、重新連接缺失的 Internet Gateway),修復後不帶 skip 地呼叫 ContinueUpdateRollback。如果某個資源確實無法恢復,跳過它——CloudFormation 無論實際狀態如何都將其標記為 UPDATE_COMPLETE,後續協調成為你的責任。刪除並重建會摧毀所有 Stack 資源,包括健康的資源,在 SOA-C02 上這是錯誤的第一個答案。
Q2:什麼時候使用 DeletionPolicy: Retain vs Snapshot vs 保留預設值?
對於必須在 Stack 之後繼續存在且無法從快照重建的資源,使用 Retain——KMS CMK(被 Stack 外部的密文引用)、存放生產資料的 S3 bucket、跨帳號引用的 IAM 資源。對於最終時間點副本足夠用於還原的有狀態資源,使用 Snapshot——RDS DB instances、EBS volumes、ElastiCache clusters、FSx file systems。對於從 template 重建成本低廉的無狀態資源,保留預設的 Delete——launch template、security group、與 Stack 緊密耦合的 IAM 角色。同樣的規則適用於 UpdateReplacePolicy——在每個有狀態資源上同時設定兩個屬性。
Q3:什麼時候應該使用 Change Set?
生產 Stack 更新一律使用。Change Set 預覽每個資源變更,包括會銷毀資料的重要替換事件。代價是在 execute-change-set 之前多一個指令;好處是防止意外資料遺失。對於新 Stack,Change Set 在 template 有條件資源且最終組成取決於參數值時很有用——在提交前審查將建立哪些資源。對於非生產環境,直接 UpdateStack 對於速度可能可以接受,但成熟的 SysOps 團隊在每個環境都要求 Change Set 作為習慣。
Q4:如何將 CloudWatch alarm 基準部署到組織中的每個帳號?
使用啟用自動部署的 service-managed StackSet,定向到根 OU 或基準 OU。前提條件:具有所有功能(不僅是合併帳單)的 AWS Organizations、為 CloudFormation 啟用的受信任存取,以及若你想從非管理帳號管理 StackSets 則需要委派管理員帳號。StackSet template 定義 alarm;自動部署確保加入 OU 的每個新帳號自動獲得 alarm。Self-managed StackSets 無法自動部署——它們需要明確的帳號 ID 和手動的 IAM 角色佈建。在幾乎所有「部署到所有組織帳號」的情境中,考試答案都是 service-managed StackSets。
Q5:CloudWatch alarm 的 treatMissingData 與 Rollback Trigger 有什麼關係?
作為 Rollback Trigger 引用的 CloudWatch alarm 依照其自己的設定評估。如果 alarm 在監控視窗期間處於 INSUFFICIENT_DATA,它不會被視為回滾目的的 ALARM——只有明確轉換到 ALARM 才會觸發回滾。因此,treatMissingData: missing 且沒有最近資料點的 alarm 停留在 INSUFFICIENT_DATA 且永遠不會導致回滾。這通常是正確的行為——你不希望資料缺失來還原部署。如果你需要無聲被視為失敗,將底層 alarm 設定為 treatMissingData: breaching,使缺失的週期計為突破並讓 alarm 轉換到 ALARM。
Q6:如何防止生產資料庫透過 CloudFormation 被意外刪除?
深度防禦,四個層次:(1) RDS 資源上的 DeletionPolicy: Snapshot,使任何刪除都產生最終快照。(2) UpdateReplacePolicy: Snapshot,使更新觸發的任何替換都產生最終快照。(3) 拒絕資料庫邏輯資源 ID 上 Update:* 的 Stack policy,防止意外修改。(4) Stack 本身啟用 termination protection(UpdateTerminationProtection: true),阻止 DeleteStack API 呼叫。可選在 OU 層級新增 SCP,針對生產 Stack ARN 拒絕 cloudformation:DeleteStack。每個層次涵蓋不同的失敗模式;合在一起使意外摧毀幾乎不可能。
Q7:self-managed 和 service-managed StackSets 的差異是什麼?
Self-managed 需要操作者手動建立跨帳號 IAM 信任——管理員帳號中的 AWSCloudFormationStackSetAdministrationRole 和每個目標帳號中的 AWSCloudFormationStackSetExecutionRole。不需要 AWS Organizations。Service-managed 使用 AWS Organizations 自動建立和管理 IAM 角色,支援以 OU(而非帳號 ID)為目標,並支援自動部署到加入 OU 的新帳號。Service-managed 需要 Organizations 所有功能和為 CloudFormation 啟用的受信任存取。SOA-C02 全組織部署的預設答案是 service-managed;只有當 Organizations 未使用或需要定向特定固定帳號清單時,self-managed 才是正確的。
Q8:StackSet 操作的 MaxConcurrentCount 和 FailureToleranceCount 是什麼?
MaxConcurrentCount(或 MaxConcurrentPercentage)控制 CloudFormation 在單一 region 內同時部署到幾個目標帳號。預設是 1(序列)。較高的值加快大型推出但在 template 有 bug 時增加爆炸半徑。FailureToleranceCount(或 FailureTolerancePercentage)控制操作在停止前可容忍幾個帳號失敗。預設是 0——第一個失敗停止一切。對於多帳號的生產推出,典型值是 MaxConcurrentPercentage: 25, FailureTolerancePercentage: 5——同時部署到 25% 的帳號,容忍最多 5% 失敗,只有當失敗超過容忍時才停止。
Q9:如何讓 CloudFormation template 的 AMI ID 跨 region 移植?
使用類型為 AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> 的參數,預設指向 AWS 管理的 Parameter Store 路徑。對於 Amazon Linux 2023:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64。CloudFormation 在 Stack 建立時讀取參數,無需硬寫就能獲得正確的特定 region AMI ID。舊式做法是帶有每個 region AMI ID 的 Mappings,這有效但每次 AWS 發布新 AMI 都需要手動維護。SSM Parameter Store 類型是 SOA-C02 建議的做法。
Q10:CloudFormation 何時自動回滾 vs 讓 Stack 保持失敗狀態?
預設情況下,每次 CREATE 和 UPDATE 操作在失敗時都會回滾。在 CREATE 時停用此行為的旗標是 --disable-rollback(或 API 中的 OnFailure: DO_NOTHING),讓 Stack 保持在 CREATE_FAILED 以便檢查。更新沒有等效旗標;更新始終自動回滾。如果回滾本身失敗,Stack 進入 UPDATE_ROLLBACK_FAILED 並等待 ContinueUpdateRollback。Rollback Trigger 是在操作期間和之後監控 CloudWatch alarm 的額外層次;如果觸發器 alarm 觸發,CloudFormation 即使操作技術上成功也會啟動回滾——適合捕捉只有在部署後才顯現的應用程式層級回歸。
Q11:CloudFormation 操作會記錄什麼?
每個 CloudFormation API 呼叫都出現在 CloudTrail 管理事件中——CreateStack、UpdateStack、DeleteStack、ExecuteChangeSet、CreateChangeSet、DetectStackDrift、CreateStackInstances 等。每個事件記錄呼叫者(使用者或 service role)、參數和回應。對於 CloudFormation 建立的資源,資源層級事件由各自的服務記錄(例如 EC2 的 RunInstances 事件)。CloudFormation API 事件加上資源服務事件的組合提供完整的取證可見性。對於敏感 CloudFormation 操作的即時警示,將 CloudTrail 路由到 CloudWatch Logs,並對生產 Stack ARN 的 DeleteStack 或 UpdateStack 等事件名稱建立 metric filter 或 EventBridge rules。
Q12:Stack 達到 UPDATE_COMPLETE 後如何回滾特定變更?
CloudFormation 沒有「git revert」操作。兩條路:(1) 重新部署先前的 template 版本。在 Git 中保留 template,識別先前的 tag 或 commit,並以該 template body 執行 UpdateStack。Change Set 顯示將還原的內容。(2) 主動使用 Rollback Trigger——以應用程式錯誤率上的 CloudWatch alarm 作為 Rollback Trigger,監控時間 30 分鐘,任何部署後回歸在 Stack 最終確定之前觸發自動回滾。一旦達到 UPDATE_COMPLETE 且監控時間到期,你必須手動重新部署先前的 template。沒有「撤銷上次更新」的指令。
延伸閱讀與相關運維模式
- AWS CloudFormation User Guide — Welcome
- Creating a Stack on the AWS CloudFormation Console
- Updating Stacks Using Change Sets
- Detecting Unmanaged Configuration Changes (Drift)
- DeletionPolicy Attribute
- UpdateReplacePolicy Attribute
- Prevent Updates to Stack Resources (Stack Policies)
- Monitor and Roll Back Stack Operations (Rollback Triggers)
- Continue Rolling Back an Update
- Working with AWS CloudFormation StackSets
- StackSets Concepts
- Service-Managed StackSets — Trusted Access with Organizations
- Self-Managed StackSet Permissions
- Intrinsic Function Reference
- Troubleshooting CloudFormation
- AWS CloudFormation Service Role
- AWS SOA-C02 Exam Guide v2.3 (PDF)
CloudFormation 佈建穩固之後,後續的運維層次包括:AMI 生命週期與 EC2 Image Builder,提供 CloudFormation 部署的成品;Systems Manager Automation 和 Patch Manager,作為操作 CloudFormation 部署資源的 runbook 引擎,本身通常也由 CloudFormation 管理;使用 AWS Organizations 和 Control Tower 的多帳號策略,作為 service-managed StackSets 和 SCP 運作的組織層級容器;以及排程任務和 Config 自動補救,作為偵測 Drift 並觸發 CloudFormation 更新或 SSM runbook 的事件驅動自動化。