2026 年 2 月底,一個線上學習社群的營運者使用 Claude Code 操作 Terraform,結果刪除了生產環境的 RDS 資料庫以及所有快照。2.5 年的課程營運資料(僅作業提交表就約 194 萬筆)在瞬間消失的事故。
讀完這篇我覺得很可怕。自己也日常使用 Claude Code,類似情境任何時候都有可能發生。整理事故經過的同時,也想重新確認那些理所當然但容易忽略的基本事項。
受害的是名為 DataTalks.Club 的線上學習社群的生產環境。營運者 Alexey Grigorev 想把另一個側案(AI Shipping Labs)合併到同一個 AWS 基礎建設中,以每月省下 5~10 美元為目的。
事故重點如下:
apply 時建立了重複資源terraform destroy,整個生產環境被刪除結果 VPC(虛擬私有雲)、RDS、ECS、負載平衡器、跳板主機,以及自動快照等全部被毀。
他把支援升級到 AWS Business Support(他的情況下雲端費用約增加 10%),AWS 幫忙在主控台看不到的情況下找到了快照,約 24 小時後成功還原了資料,算是不幸中的大幸。
把這起事故簡化為「把基礎建設交給 AI 管理太冒險」當然很容易。但老實說,回頭看自己的環境也能發現類似風險。
每天使用 Claude Code 時,成功經驗會累積,對操作的再確認門檻會降低。產生程式碼、跑測試、操作 git,一切順利的次數愈多,就愈容易忽視確認。對 Terraform 的 plan 與 apply 也可能覺得只是「平常的延伸」,那就是最可怕的地方。
Grigorev 想整合基礎建設以節省每月 5~10 美元。你可能會想「就那麼一點錢」,但「這種程度的變更應該沒問題」這類判斷,不論金額大小,誰都可能做出。
以下內容並不新奇,都是處理基礎建設時應該知道的事。但「知道」與「實際做到了」之間往往有距離。這起事故促使我檢查自己的環境。
事故後 Grigorev 決定「不將破壞性指令委由 AI」。像 terraform destroy、terraform apply、rm -rf、DROP TABLE 這類操作,很難回復。
若是使用 Claude Code,可以在設定中加入限制。
settings.json
<span>{</span><span>
</span><span>"permissions"</span><span>:</span><span> </span><span>{</span><span>
</span><span>"deny"</span><span>:</span><span> </span><span>[</span><span>
</span><span>"Bash(terraform destroy *)"</span><span>,</span><span>
</span><span>"Bash(terraform apply *)"</span><span>,</span><span>
</span><span>"Bash(rm -rf *)"</span><span>
</span><span>]</span><span>
</span><span>}</span><span>
</span><span>}</span><span>
</span>
可以把產生 plan 的步驟交給 AI,但把 apply 留給自己在確認後手動執行。建議確認你使用的工具是否具備這類機制。
deny 規則並非萬無一失,仍可能被繞過。若是團隊共用,建議同時檢查 disableBypassPermissionsMode 等設定以提高安全性。
這次事故的根本原因是 state 檔案放在本地,換電腦時遺失,導致 Terraform 無法辨識既有基礎建設。
backend.tf
<span>terraform</span> <span>{</span>
<span>backend</span> <span>"s3"</span> <span>{</span>
<span>bucket</span> <span>=</span> <span>"my-terraform-state"</span>
<span>key</span> <span>=</span> <span>"production/terraform.tfstate"</span>
<span>region</span> <span>=</span> <span>"ap-northeast-1"</span>
<span>encrypt</span> <span>=</span> <span>true</span>
<span>use_lockfile</span> <span>=</span> <span>true</span>
<span>}</span>
<span>}</span>
過去常用 dynamodb_table 來鎖定 state,但現在建議使用 use_lockfile = true。
別再心想「改天再做」,趁現在確認一下自己的 state 是否已經遷到 S3 等遠端。
RDS 有個名為 deletion_protection 的設定。
rds.tf
<span>resource</span> <span>"aws_db_instance"</span> <span>"production"</span> <span>{</span>
<span># ...</span>
<span>deletion_protection</span> <span>=</span> <span>true</span>
<span>lifecycle</span> <span>{</span>
<span>prevent_destroy</span> <span>=</span> <span>true</span>
<span>}</span>
<span>}</span>
deletion_protection 是 AWS 端的設定,啟用時會阻止刪除資料庫實例。prevent_destroy 則是 Terraform 端的保護,若設定為 true,terraform destroy 的計畫會被拒絕。兩者機制不同,但同時設定可以雙重防護,減少意外刪除風險。不過兩者都可以被修改而解除保護,因此務必確認實際值是否如你所預期。
Grigorev 在事故後做的一個印象深刻的對策是,每晚自動執行備份還原測試。
備份「存在」與「能還原」是兩回事。RDS 的自動備份(automated backups)在刪除 DB 實例時會一同被刪除;手動快照(manual snapshots)會保留,但這次事故中也沒有建立手動快照。以為有備份就安全可能是錯誤的假設,實際做過還原測試才能確認可用性。
我自己也有做備份,但坦白說沒做過還原測試。
若在同一個 AWS 帳號中混放生產與開發環境,事故的影響範圍會擴大。使用 AWS Organizations 分帳號管理,幾乎不會增加成本,但把已在運行的環境拆分出去會比較麻煩。
若是新建立環境,從一開始就分開會比較輕鬆。
這起事故讓我最有感的一點是「我已核可」這個動作的意義。
Claude Code 在執行命令前會要求使用者確認。Grigorev 也核准了 terraform destroy 的執行,但當時他並沒有完全理解「會被刪除的是什麼」。
當 AI 代理提出的操作變得複雜時,核可就有變成形式化的風險。尤其是基礎建設操作,一條命令的影響範圍可能非常大且難以回復。
我最近在按核可鍵前會自問:「我能用一句話說出這會破壞哪些東西嗎?」如果說不清,代表還沒充分理解,不應該按下核可。
回頭看,這起事故的教訓多半都是基本功:
確認清單 — 我的環境沒問題嗎?
「知道」與「實際做到」是兩件事。我也因為這起事故重新檢視並清點了自己的環境。希望讀者也能藉此檢查自己的配置,降低類似風險。