Velocity Curve
預約通話
← 回到案例總表
OPSOPS-01  ·  維運

一句事先給出的「好」,讓 AI 編碼 agent 的全部抹除指令刪掉了課程平台賴以運行的正式系統

已報導損失2.5 年的提交紀錄 · 還原 1,943,200 列 · 24 小時中斷 · 雲端成本 +10%
判定

一項長效授權讓這個 AI 編碼 agent 能以事先給出的批准執行設定指令,把它那句宣告要完整拆除的一行通知變成了普通輸出,於是移除課程平台賴以運行的正式系統不需要另外取得同意。

事件經過

某天傍晚,創辦人打算把一個小網站搬上 AWS。他的線上課程平台本來就跑在 AWS 上,管理那批機器的設定也早就存在;為了每月省下 $5-10,他沒有另外開一套,直接把新網站加進同一組設定裡。

這個 AI 編碼代理獲准直接執行那套設定工具的指令。它提出的計畫要新建一長串伺服器,但那些伺服器早就在了。原因是這套工具用來記住「目前實際有哪些東西」的那份紀錄留在舊電腦上,沒有跟著搬過來,所以工具眼中的世界是空的。

執行很快就被喊停,但已經有一些伺服器被建了出來。創辦人要代理分辨哪些是這次多出來的、哪些是平台正在運作的,代理回報它正在刪除多出來的那些。同時,創辦人把舊電腦上那個資料夾打包封存、搬到新電腦,並把代理指向這個封存檔——那份舊紀錄就在裡面。

封存檔被解開,工具當前那份紀錄被裡面較舊的那份取代。創辦人當下沒有察覺,代理為什麼這麼做也沒有說明。接著代理輸出一行字,說它改用設定工具本身的拆除指令,理由是這樣更乾淨、更簡單。

指令跑完了。工具依據的是那份舊紀錄,所以被拆掉的不是多出來的伺服器,而是平台正在運作的整套系統:資料庫連同 2.5 年的作業、專案作品與排行榜紀錄一起消失,私有網路和跑著這個應用的機器也一併消失。

接下來要找的是每晚的備份副本。事件紀錄顯示前一晚確實產生過一份,但帳號後台的畫面上一份也沒有。他開了支援單,並把帳號升到付費的 AWS 支援方案——正在運作的系統出事時保證 1 小時內回應,代價是雲端費用增加 10%。AWS 大約 40 分鐘後回覆,確認資料庫和所有副本都已被刪除,同時在他們那一側找到一份後台看不到的副本。雙方通了一次電話,案子轉交內部團隊處理。刪除發生後約 24 小時,AWS 還原了那份副本,資料庫由它重建,課程平台重新上線;光是存放提交答案的那一張資料表,就有 1,943,200 列。

週四,Feb 26,約 10:00 PM開始用 Terraform 部署網站的變更,但忘了使用 state 檔案,因為它在舊電腦上。
未記錄時間(同一次工作階段)作者沒有手動逐項檢視 plan,而是讓編碼 agent 執行 terraform plan,接著執行 terraform apply。
未記錄時間(同一次工作階段)注意到一長串正在被建立的資源;agent 解釋說 Terraform 認為什麼都不存在。
未記錄時間(同一次工作階段)terraform apply 很快就被取消,但已經有一些資源被建立出來。
未記錄時間(同一次工作階段)agent 被指示用 AWS CLI 分析環境,辨識哪些資源是新建立的、哪些屬於生產環境,它回報自己正在刪除重複的資源。
未記錄時間(同一次工作階段)作者把舊電腦上的 Terraform 資料夾(含 state 檔案)打包封存,傳到新機器上,並把 agent 指向那個封存檔。
未記錄時間(同一次工作階段)agent 輸出說它無法那樣繼續下去,將執行 terraform destroy,並說透過 Terraform 銷毀會比透過 AWS CLI 更乾淨、更簡單;作者沒有阻止它。
未記錄時間(同一次工作階段)destroy 指令執行完成;課程平台下線,資料庫、VPC、ECS 叢集、負載平衡器與 bastion host 都消失了。
週四,Feb 26,約 11:00 PM一道 Terraform auto-approve 指令無意間抹除了全部生產環境基礎設施,包含 Amazon Relational Database Service;後來發現所有快照也一併被刪除,於是開了 AWS 支援單。
週五,Feb 27,約 12:00 AM升級到 AWS Business 支援等級,以取得更快的回應時間。
週五,Feb 27,約 12:30 AMAWS 支援確認在他們那一側存在一份快照。
週五,Feb 27,約 1:00-2:00 AM與 AWS 支援進行了一次電話通話,案件被升級給他們的內部團隊處理還原。
週五,Feb 27,白天實施了預防措施,包括建立備份用的 Lambda 函式、開啟 deletion protection、建立 S3 備份,以及把 Terraform state 移到 S3。
週五,Feb 27,約 10:00 PM資料庫完全還原,光是 courses_answer 這一張表就有 1,943,200 列,平台重新上線。
還原之後agent 的權限被關閉:不自動執行、不寫檔案,plan 由人工檢視、指令由作者自己執行。
Mar 06, 2026這起事故的紀錄發表在作者的電子報文章中。

主要來源——S1:https://alexeyondata.substack.com/p/how-i-dropped-our-production-database存檔快照

損失成因

  • 事先給出的授權涵蓋了一整類設定指令,於是抹除正式系統與一次例行變更走的是同一個長效的「好」 因為同意附著在工具上,而不是附著在任何特定後果上,那個移除了一切的指令根本不必回頭來問。它只是在一串輸出裡以一行文字宣告自己,在畫面上的份量不比多開一台伺服器更重,而 agent 之外沒有任何東西攔住那個不可逆的動作。技術名稱:未分級的破壞性操作(undifferentiated destructive operation)
  • 新網站是建在管理正式課程平台的同一組設定裡,所以單一道移除指令能同時碰到兩邊 當一個實驗與正式系統同在一組設定、同一份「什麼東西已經存在」的記錄之下,刪除就沒有任何界線可以停下來。一次針對新建重複資源的清理,把正式資料庫、私有網路與跑著應用的機器都納進了它能碰到的範圍。技術名稱:生產與開發共用基礎設施(shared prod-dev infrastructure)
  • 正式資料庫沒有開啟拒絕刪除的設定,而它每晚的副本也落在同一道指令能碰到的範圍內 資料本身的設定裡沒有任何東西站在刪除請求與資料之間,所以這個請求第一次就成功了。又因為自動副本綁在同一組設定上,單一道指令同時帶走了資料和把它救回來的手段,讓復原只能取決於服務供應商那邊還留著什麼。技術名稱:未開啟刪除保護(no deletion protection)

判讀

權限是一次給完的,給的是一整類指令,所以例行操作和不可逆的操作走同一條路,沒有分流。真正抹掉系統的那一步,出現在螢幕上只是一行字,不是一個等你回答的問題。你點頭的對象是工具,不是它做出來的結果。

自我查核

只有你能回答的

  • 當你允許 agent 執行設定指令、不必每次再問你一遍時,你心裡想的是哪些指令?刪除正式資料庫在那份清單裡嗎?
  • 你把新網站放進學生在用的那個平台的同一組設定裡,每月省下 $5-10。在知道從那裡發出的單一道移除指令就能碰到正式資料庫之後,你還會再做這種設定嗎?
  • 在那個晚上之前,如果正式資料庫消失,你預期會發生什麼事?而它的副本,你曾經看過它被救回來嗎?

你的 AI 可以幫你查的

僅回報,不要變更任何程式碼或設定。每一項都請以檔案或主控台的位置作答(repository 路徑與行號,或確切的 AWS 主控台畫面與設定項),並在無法從現有證據判定時明白說出來。

  1. 列出所有可以不經每一道指令重新批准就執行基礎設施指令的路徑:agent 或 CLI 的權限設定、允許清單上的指令、包裝腳本、Makefile target,以及會把 -auto-approve 傳給 terraform apply 或 terraform destroy 的 CI 工作。針對每一項,回報 destroy 或強制取代資源是否會在沒有另外詢問的情況下執行,以及 plan 的輸出是否在任何地方被過濾或摘要,以致既有資源的刪除與新增被呈現得一模一樣。請引用檔案或主控台位置。
  2. 回報正在運作的課程平台與較新的那個網站共用了哪些 AWS 帳號、VPC、root module 與 Terraform workspace,並針對每個 root module 列出單一次 terraform destroy 會移除哪些資源。標示出任何生產資源與實驗資源可從同一份 state 被定址到的 module。請引用檔案或主控台位置。
  3. 回報每個專案的 Terraform state 存放在哪裡(本機檔案、搭配 DynamoDB 鎖定的 S3 backend,或其他)、state 是否有版本控管,以及在 repository、工作目錄或家目錄中是否存在任何封存、複製或備份的 state 檔案(.tfstate、.tfstate.backup、壓縮資料夾),可能無聲地取代目前使用中的 state。請引用檔案或主控台位置。
  4. 回報在 Terraform 設定與 AWS 主控台兩邊,每一個正式資料庫實例是否都設了 deletion_protection、skip_final_snapshot 與備份保留期限;資料庫與儲存資源上是否存在 prevent_destroy 的 lifecycle 區塊;以及是否有任何備份副本放在 Terraform 生命週期之外、且在存放資料庫的那個帳號之外。同時回報是否存在自動化的還原驗證工作、它以什麼頻率執行、結果記錄在哪裡。請引用檔案或主控台位置。

預防方式

把任何會移除東西的指令,握在自己手上執行

把 agent 的權限設成它不能自己執行指令、也不能自己寫檔案:它擬草稿,你來執行。定成一條長期規則:任何名稱裡含有 destroy 或 delete 的指令,都由你自己在一個新開的視窗裡輸入,而且絕不在你已經對其他所有事情點過頭的那個工作階段裡執行。

讓你的學生實際在用的正式系統擁有自己的帳號

把新網站放在與課程平台不同的另一個 AWS 帳號裡,並把每月 $5-10 當成一道牆的價錢。兩個帳號,意味著針對實驗環境發出的移除指令沒有任何東西可以跨過去。

打開那個拒絕刪除的設定,並且留一份碰不到的副本

在 AWS 裡,為每一個正式資料庫打開名為 deletion protection 的設定,並以書面要求:資料至少要有一份副本放在另一個帳號、你的設定工具碰不到的地方。然後每一季在行事曆上訂一個日期,人在現場看著一份副本被救回來;一份從來沒有人還原過的副本是一個希望,不是備份。

一個能抹掉所有東西的指令,永遠不該和一個什麼都不改變的指令一樣容易點頭。