最近開始大動作要將現有的 AWS 服務轉由 CloudFormation 受管,但也遇到各種問題 … 先說明一下這篇要紀錄的情境:
- 第一次使用 CloudFormation 建立 VPC (with Subnet, RouteTable … etc)
- 過程中因維護不善
手動
將其中幾個 Subnet 刪除 (包含 RouteTable) - CloudFormation 再次 Update 發生 Subnet-Id not found
- CloudFormation Drifts 狀態為
drift
代表 CloudFormation 與實際 Resource 有不一致的情況發生。
在整個團隊還沒有很一致的 CloudFormation 管理基礎下很容易有這樣的問題,然後就要開始解自己造成的技術債 …
找到這篇 AWS 提供的解法,Short Description 基本上是幹話 XDD …,就是叫你不要手動 Update CloudFormation 管的 Resource
If you delete a resource from an AWS CloudFormation stack, then you must remove the resource from your AWS CloudFormation template. Otherwise, your stack fails to update, and you get an error message.
基本上解法有兩種情境,關鍵在於 Physical ID 的關聯,詳情看[1]
Static-Physical ID Resources
像是 IAM Role, S3 這種固定的 Physical-Id 可以直接手動
建回來,然後再 Update CloudFormation 就好,步驟如下:
- 檢查 CloudFormation Template 建立的 Resource name,舉例為 Example-Role (IAM Role)
- 建立名為 Example-Role 的 IAM Role
- CloudFormation 重跑 Drifts 確認狀態為
IN_SYNC
- CloudFormation 再次 Update 確認 change set 是沒有異動
- CloudFormation Execute
Dynamic-Physical ID Resources
多數 Resource 都是 Dynamic-Physical ID,基本上只能從 CloudFormation 移掉已被刪除的 Resource
,有需要重建再從 CloudFormation 建回來,步驟蠻簡單的,但因為是 Delete 所以要更謹慎的確認:
- 將手動刪除的 Resource 從 CloudFormation 刪掉
- Update CloudFormation,確認狀態為 Remove
- 檢查 change set 的 JSON changes 確實為手動刪除的 Resource (極為重要)
- CloudFormation Execute
- 因為該 Resource 不存在,所以只有 CloudFormation Stack 會動。
- CloudFormation 更新成功。
延伸閱讀
[1]: CloudFormation 每一個 Resource 都具有由使用者指定的唯一值 Logical ID,除此之外還有實際分配給這個 Resource 的 Physical ID,但 Physical ID 並不是每個服務都能由使用者指定,大致上分為兩種型態:
- Static-Physical-ID Resources:基本上是以 Resource Name 命名,並且可以重建相同的 Physical ID 回來,像是 IAM Rolename, S3 Bucketname。
- Dynamic-Physical ID Resources:亂數或是特定分類命名,並且每次建立都不一樣,無法預先知道建立的 Physical ID,像是 Subnet-Id、Instance-Id … etc
絕大多數的服務都是 Dynamic-Physical ID 為主,對於 AWS 來說是相對好管理。