一切始於一封帳單警示。
預估費用已超過 $250。雖然金額不算驚人,但足以讓我去查看。真正引起我注意的不是金額,而是這個警示本身。我顯然在某個時間點設定過它,而這個門檻感覺已經過時了。
於是我開始尋找這個警示存在的位置。
它來自我 2014 年建立、之後完全忘記的 BillingAlerts CloudFormation Stack。一個我早已忘記的東西,竟然在提醒我其他所有被遺忘的東西。
我打開 Stack 清單,這才發現它並不孤單。它排在一長串 Stack 之中,而我對其中一半都不熟悉。這是多年累積下來的殘留物,就這麼靜靜地待在那裡。
你所遺忘的東西不會造成任何問題。它不會在凌晨 2 點呼叫你。它只是靜靜地待在那裡,不斷產生費用,直到你查看發票時,才發現自己對其中一半的東西毫無印象。被遺忘但仍在運行的資源,是雲端支出浪費的最大來源之一,根據某些估計約佔平均雲端預算的四分之一。
我本來只是想更新一個警示,結果卻發現了一團亂。
必須說明,這些 Stack 其實沒有造成我太多損失。有些是已停止的 EC2 執行個體,有些是半刪除的殘留物。如果它們真的造成 $252 的費用,這個警示應該每個月初都會觸發。但這正是重點。在清除雜亂之前,你無法得知哪些東西真正造成費用。
所以警示可以稍後再處理。我想先把這些過時的 Stack 清除掉。
通常這是一項雜務。打開主控台,找到每個 Stack,點擊刪除,等待,重新整理,檢查是否成功,或者手動撰寫 CLI 指令。這件事不難,只是很繁瑣。這類工作我總是拖延。
而這正是事情的起點。透過主控台進行 ClickOps。我剛剛手動刪除孟買區域的一個舊 Directory Service 目錄,花了不到十分鐘的點擊和等待,這時我突然想到:我還有更多 Stack 要刪除。我不需要親自處理這些事情。
為什麼我還在點擊?
我開啟 Kiro,它內建 Agent Toolkit for AWS,我直接描述我想要做的事情。我在之前的部落格文章 I Switched to the Agent Toolkit for AWS. Here's Why. 中提過如何設定它。
沒有主控台,沒有 CLI。我直接與 Agent 對話,讓它處理剩下的事情。就像一個好助手!
如果你已安裝 AWS CLI,只要執行:
aws configure agent-toolkit
Enter fullscreen mode Exit fullscreen mode
首先,顯示有哪些資源
我先請 Agent 列出我所在區域的 CloudFormation Stack。
它回傳了 12 個 Stack。有些我認得,有些則很古老,包括 2014 年的 billing-alerts Stack、2021 年的幾個修補和合規 Stack,以及 CDK bootstrap 工具包。接著就是我真正想刪除的那些。
我挑選了四個 Stack,並告訴 Agent 刪除它們。
它在刪除前會先確認
這很重要,所以我想特別提出來。
Agent 並沒有在我提出要求後立即開始刪除。在執行任何動作之前,它會先把這四個 Stack 列出來,清楚告訴我這會移除所有資源且無法輕易復原,並要求我確認。
刪除基礎設施是不可逆的。
我說可以之後,它才開始執行。
我得到了「交給它處理」的速度,同時又保有對破壞性操作的確認機制。
它以程式碼方式檢查結果,無需每秒重新整理主控台
刪除請求送出後,Agent 撰寫了一段指令碼並在工具包的沙箱中執行,以同時檢查這四個 Stack 的狀態。
它同時檢查這四個 Stack,處理 Stack 可能已經不存在的情況,並回傳乾淨的狀態對應表。所有操作都在遠端沙箱中使用 boto3 執行。我的電腦從未執行任何程式碼。
三個 Stack 順利刪除,但有一個拒絕刪除。
第四個 Stack aws-sam-cli-managed-default 回傳 DELETE_FAILED。
於是 Agent 提取 Stack 事件來找出原因。失敗指向一個資源,也就是 SAM 用於部署成品的 S3 儲存貯體(SamCliSourceBucket)。訊息很明確:
您嘗試刪除的儲存貯體不是空的。您必須刪除儲存貯體中的所有版本。
這個儲存貯體已啟用版本控制。所以「清空儲存貯體」還不夠。每個物件版本和每個刪除標記都必須移除,否則 CloudFormation 仍然無法刪除該儲存貯體。這就是為什麼在主控台中快速「清空」有時無法解決問題的原因。
Agent 解釋了原因,然後提出要正確清空儲存貯體並重試。我同意了。
整個過程——記住版本控制儲存貯體的陷阱、找出儲存貯體名稱、意識到刪除標記也需要計算、手動清空,然後返回重試——這通常是我自己要慢慢處理的部分。Agent 將刪除失敗與未清空的儲存貯體連結起來,並直接處理了它。
四個 Stack 全部清除。
為什麼這感覺不一樣
讓我清楚說明這裡真正改變了什麼,因為「我使用 AI 刪除了一些 Stack」不是重點。
重點是整個流程都留在同一個地方。我用白話描述目標。Agent 列出我帳戶的實際狀態、確認破壞性操作、執行程式碼完成工作,然後在沒有我查閱文件的情況下,偵錯並修復發生問題的部分。
有幾個因素讓這成為可能:
它安全地執行真實程式碼。 工具包為 Agent 提供帶有 boto3 的沙箱 Python 執行環境。它可以用幾行程式碼檢查狀態、篩選並執行操作,而無需在我的筆電上執行任何東西。
它會確認風險操作。 刪除是單向操作。Agent 將其視為單向操作,並先徵求我的同意。
它端到端處理失敗。 主控台不會讓我卡在這裡。遇到 DELETE_FAILED 時,它會跳出視窗讓我重試,要麼保留儲存貯體(在我的帳戶中孤立它),要麼跳轉到 S3 主控台自行清空。這兩者都是情境切換,而「保留」只是讓儲存貯體留在後面。Agent 跳過了所有這些步驟。它讀取 Stack 事件、找到版本控制的儲存貯體、正確清空它(包括版本和刪除標記),然後重試,無需我離開聊天或孤立任何東西。
一切都可稽核。 因為所有操作都透過受管理的 AWS MCP Server,每次呼叫都會記錄在 CloudTrail 中。更多細節請見下一節。
我可以在 CloudTrail 中看到每一次呼叫
這部分讓「我讓 Agent 刪除我的基礎設施」從可怕變得可以接受。
Agent 執行的每個動作都經過受管理的 AWS MCP Server,而這些呼叫都會出現在 CloudTrail 中。我去查看了。所有四個 DeleteStack 事件都在我的身分下清楚顯示,並帶有明確的指紋:
eventName: DeleteStack
userIdentity: gaonkarr
sourceIPAddress: aws-mcp.amazonaws.com
userAgent: aws-mcp.amazonaws.com
Enter fullscreen mode Exit fullscreen mode
aws-mcp.amazonaws.com 這個值就是你區分 Agent 操作與你自己操作的方式。當天稍早,我曾在主控台手動刪除一些 Stack,而那些事件看起來完全不同:真正的瀏覽器使用者代理和我的實際 IP 位址。所以稽核軌跡清楚顯示誰真正做了什麼,我的點擊操作與 Agent 代表我執行的操作。
以下是這次清理工作的五個 DeleteStack 事件,直接來自 CloudTrail:
| 時間 (UTC) | Stack | 身分 | 來源 IP | 使用者代理 |
|---|---|---|---|---|
| 14:23:18 | CdkPipelineStack | gaonkarr | aws-mcp.amazonaws.com | aws-mcp.amazonaws.com |
| 14:23:18 | buildon-sam-app | gaonkarr | aws-mcp.amazonaws.com | aws-mcp.amazonaws.com |
| 14:23:18 | aws-sam-cli-managed-default (第一次嘗試) | gaonkarr | aws-mcp.amazonaws.com | aws-mcp.amazonaws.com |
| 14:23:19 | sam-app | gaonkarr | aws-mcp.amazonaws.com | aws-mcp.amazonaws.com |
| 14:24:19 | aws-sam-cli-managed-default (重試) | gaonkarr | aws-mcp.amazonaws.com | aws-mcp.amazonaws.com |
重試操作清楚記錄在軌跡中。aws-sam-cli-managed-default 的刪除出現了兩次:一次是失敗時,另一次是在 Agent 清空儲存貯體後大約一分鐘的重試。整個失敗後修復的序列都被保留下來。
有一個值得注意的誠實提醒:DeleteStack 呼叫屬於管理事件,CloudTrail 預設會記錄這些事件。但實際清空儲存貯體的 S3 DeleteObjects 呼叫屬於資料事件,除非你已為該儲存貯體啟用資料事件記錄,否則這些事件不會被記錄。所以我可以清楚看到 Stack 刪除,但看不到個別物件刪除。如果你想要軌跡中的物件層級操作,必須先啟用 S3 資料事件記錄。
接下來我要做什麼
刪除四個 Stack 感覺很不錯。所以我好奇地問 Agent:
你能掃描我的 AWS 帳戶並找出任何殘留資源嗎?
它掃描了我帳戶中的常見服務。先是預設區域,然後擴展到其他區域。列出了 4 頁以上的內容。🫣
它發現了大量來自工作坊、示範和舊專案的殘留資源,並提供了成本影響摘要。
3 個已停止的 EC2 執行個體,最舊的一個來自 2021 年。
14 個未附加的 EBS 磁碟區,有些是 2014 年建立的,仍然默默地為未附加到任何東西的儲存空間產生費用。
5 個未關聯的 Elastic IP,每月約 $18,用於沒有任何作用的位址。
122 個 S3 儲存貯體、一個我忘記的負載平衡器、16 個 Lambda 函數全都使用多年前就已到達生命週期結束的執行環境。
這些都不會造成任何問題。這正是它們能存活這麼久的原因。
找出所有這些通常是最困難的部分。逐一瀏覽每個服務、在每個區域中操作,這是我從不做這件事的原因。在刪除任何東西之前,這需要數小時的繁瑣工作。這一次我只問了一次,Agent 就把整個清單交給了我。
這個一直覺得太大而無法開始的工作,現在變成了簡單的部分。
所以我將在新助手的幫助下清理它。
如果你的帳戶和我的一樣,你也應該這麼做。
告訴我你在裡面找到了什麼。我敢打賭我不是唯一忘記它的人。









0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.