iT邦幫忙

2025 iThome 鐵人賽

DAY 21
0
Build on AWS

從一個網站的誕生,看懂 AWS 架構與自動化的全流程!系列 第 21

Day 21 聰明檔案管理:S3 Lifecycle x Lambda 自動化版本控制與清理

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20251006/20172743Z8yHauYSl5.png

一、前言

在長期運行的會員網站中,檔案不斷被上傳與更新,如果沒有規劃檔案清理與版本管理,S3 Bucket 的儲存空間將會快速膨脹,造成 儲存成本增加管理困難。因此,我們需要結合 S3 Lifecycle 規則Lambda 自動化清理流程,確保檔案能依照策略被管理,例如:舊版本自動移轉到 Glacier、過期檔案自動刪除。

這個 Lab 的定位在於 長期檔案治理,透過規則化與自動化,降低人工管理的負擔。
(1) Lifecycle 解決 大部分靜態規則(例如 30 天後刪除、90 天後轉冷存)。
(2) Lambda 則負責 客製化邏輯(例如刪除特定會員的檔案、清理黑名單使用者上傳的內容)。
在整體 Serverless 架構中,它是 檔案生命週期管理模組,讓系統具備智慧化的檔案治理能力。

二、需要使用到的服務

  1. Amazon S3:檔案儲存,啟用版本控制(Versioning)。
  2. S3 Lifecycle Rule:自動將檔案轉換儲存層級或刪除。
  3. AWS Lambda:處理特殊清理需求,例如檢查 DynamoDB 紀錄後刪除特定檔案。
  4. Amazon CloudWatch Events / EventBridge:定期觸發 Lambda,執行清理任務。
  5. DynamoDB(可選):紀錄檔案屬性、過期時間、使用者狀態。

三、架構/概念圖

https://ithelp.ithome.com.tw/upload/images/20251006/20172743vRGDUGWeDZ.png

四、技術重點

  1. Versioning 必須開啟:否則檔案被覆蓋後無法復原。
  2. Lifecycle 規則與 Lambda 區分職責
    • Lifecycle:處理一般化、大批量的檔案管理。
    • Lambda:處理需要商業邏輯的客製化清理。
  3. 日誌與稽核:Lambda 執行刪除動作時,建議寫入 CloudWatch Logs 或 DynamoDB,保留審計紀錄。
  4. 結合標籤管理:針對 S3 物件使用 Tag(例如 userId, fileType),在 Lifecycle 規則中設定條件,更精準地控制檔案清理。
  5. 成本最佳化:對於不常用的檔案,建議儲存於 S3 Glacier Deep Archive,儲存費用可降低 80% 以上。

五、Lab流程

1️⃣ 前置作業

1. 建立一個啟用 Versioning 的 S3 Bucket。(Day5已創建)

https://ithelp.ithome.com.tw/upload/images/20251006/20172743OXR2OiAyPC.png

2️⃣ 主要配置

1. 設定 S3 Lifecycle 標準規則 - 刪除過期舊版本

  1. 進入「S3」頁面。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743GqY6i01u9y.png

  2. 進入儲存桶內。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743d3lsw8WFBy.png

  3. 新增一個「生命週期規則」。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743ck5jBTQYdn.png

  4. 選擇篩選條件,並設定要執行的動作。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743oj9q0cqWWL.png
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743NxelJe1MNX.png

  5. 完成畫面。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743beXE852Z3j.png

2. 設定 S3 Lifecycle 標準規則 - 冷存歸檔

  1. 再新增一個「生命週期規則」。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743Cqaj3DW9wf.png

  2. 選擇篩選條件,並設定要執行的動作。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743fElwrcrwML.png
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743fzY2S4u3Zx.png
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743K19AOoDtlj.png

  3. 完成畫面。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743Mg3JliphgY.png

3. 設定 S3 Lifecycle 進階規則(1) - 建立Lambda函數

💡在180內未存取的檔案,會被自動刪除。

  1. 進入「Lambda」頁面。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743QLJPBfrH68.png

  2. 創建一個新的函數。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743QGm8FAFtWt.png

  3. 輸入函數名稱,並選擇編撰語言。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743NZvo9bSH1B.png

  4. 跳過建議畫面。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743MpC43OgzcQ.png

  5. 寫入程式碼,並部署。

    • 程式碼範本:

      // index.mjs
      import { S3Client, HeadObjectCommand, DeleteObjectCommand } from "@aws-sdk/client-s3";
      
      const s3 = new S3Client({ region: process.env.AWS_REGION });
      const BUCKET_NAME = process.env.BUCKET_NAME || "secure-file-bucket-2025-lab";
      
      // 180 天(毫秒)
      const MAX_AGE_MS = 180 * 24 * 60 * 60 * 1000;
      
      export const handler = async (event) => {
          console.log("Received Event:", JSON.stringify(event, null, 2));
      
          const records = event.detail?.object ? [event.detail.object] : [];
          let deletedCount = 0;
      
          for (const obj of records) {
              const key = obj.key;
              console.log(`🔍 Checking object: ${key}`);
      
              try {
                  // 取得 metadata (最後修改時間)
                  const head = await s3.send(new HeadObjectCommand({
                      Bucket: BUCKET_NAME,
                      Key: key
                  }));
      
                  const lastModified = new Date(head.LastModified).getTime();
                  const ageMs = Date.now() - lastModified;
      
                  if (ageMs > MAX_AGE_MS) {
                      console.log(`🗑️ Deleting object: ${key} (Age: ${Math.round(ageMs / (24*3600*1000))} days)`);
      
                      await s3.send(new DeleteObjectCommand({
                          Bucket: BUCKET_NAME,
                          Key: key
                      }));
      
                      deletedCount++;
                  } else {
                      console.log(`✅ Object is still valid (Age: ${Math.round(ageMs / (24*3600*1000))} days)`);
                  }
      
              } catch (err) {
                  console.error(`❌ Error processing object ${key}:`, err);
              }
          }
      
          return { statusCode: 200, deletedCount };
      };
      
      

    https://ithelp.ithome.com.tw/upload/images/20251006/20172743pGiTa6hLBG.png

  6. 進入「組態」分頁,設定環境變數。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743XssXvMY9Wq.png

  7. 變數key「BUCKET_NAME」,Value為你在 S3 的Bucket name。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743GrPPGDhP3V.png

  8. 完成畫面。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743hFzGuwiFZw.png

4. 設定Lambda的IAM Role權限

  1. 進入「IAM 」頁面。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743lb1d3YOdYL.png

  2. 進入IAM role的頁面,點選該Lambda自動創建的IAM role。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743vywIIDuj6z.png

  3. 新增「許可政策」。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743nPrLbtTFM9.png

  4. 增加S3的「DeleteObject」、「DeleteObjectVersion」、「ListBucket」權限,授權範圍為指定的S3 bucket。
    https://ithelp.ithome.com.tw/upload/images/20251006/201727430cuQ9uVSFk.png

  5. 將授權調整為指定的S3。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743IIxYvFJLGq.png

    • S3的ARN在哪裡?
      https://ithelp.ithome.com.tw/upload/images/20251006/20172743Cu046KvJyO.png
  6. 再新增其他的權限。。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743ptNIxdLC5r.png

  7. 增加CloudWatch Logs的「CreateLogStream」權限,授權範圍為「全部」。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743Qm7fBMzs8D.png

  8. 設定「許可政策」名稱。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743Uo3y99pNTT.png

  9. 完成畫面。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743ra3G2WwxE1.png

5. 設定 S3 Lifecycle 進階規則(1) - 建立 EventBridge 規則,觸發Lambda

  1. 進入「Amazon EventBridge」頁面。
    https://ithelp.ithome.com.tw/upload/images/20251006/201727433rpoHioNrf.png

  2. 新增規則。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743XnRUVERxxQ.png

  3. 設定規則名稱及規則類型,繼續建立。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743jwumu2nDnt.png

  4. 設定排程時間。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743WyaIUv8e7t.png

  5. 設定觸發程序。
    https://ithelp.ithome.com.tw/upload/images/20251006/201727430R0MnBGbA0.png
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743Zpu6Irg8BH.png

  6. 設定標籤,此處先跳過。(正式上線時,可以依照標籤「Label」來區隔費用)
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743oRqRWnA6ZI.png

  7. 完成建立。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743qlKzI73lOR.png
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743ssJcX7cEZH.png

3️⃣ 測試驗證

1. 測試「標準規則」

  1. 上傳一個檔案,確認 S3 是否正確記錄版本。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743YxOT4r4R8b.png

  2. 選擇檔案,並上傳。
    https://ithelp.ithome.com.tw/upload/images/20251006/201727439KVCftvbAM.png

【補充】從S3上無法確認舊版本是否被 Lifecycle 規則標記為「待刪除」或是「已排入刪除佇列」。

  1. 等待約「設定日期」+1 D,就會看到被刪除了。
    💡每天UTC+0的00:00系統會自動將「符合lifecycle規則」的物件列入「刪除佇列」中,等待刪除。
    根據原廠的經驗,「us-east-1」的地區有機會延遲(因為該區域物件較多),延遲時間時間有機會長達一天,但佇列延遲並不會產生/被加收費用[1]。
    [1] AWS S3 - 管理物件的生命週期:
    https://docs.aws.amazon.com/zh_tw/AmazonS3/latest/userguide/object-lifecycle-mgmt.html
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743IMSgW36IBr.png

2. 測試「進階規則」

  1. 進入Lambda中,用Lambda頁面,儲存測試指令。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743lGuHAuw8tj.png

  2. 進行測試。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743dDPDIgEo40.png

  3. 進入CloudWatch頁面查看。
    https://ithelp.ithome.com.tw/upload/images/20251006/2017274374SM9CxHNG.png

  4. 確認有成功執行的紀錄,並且可以點進去查看Log內容。
    https://ithelp.ithome.com.tw/upload/images/20251006/20172743tS1HNODpNn.png

六、結語

今天的 Lab 讓我們完成了 檔案生命週期管理,利用 S3 Lifecycle 處理自動化規則,再搭配 Lambda 強化靈活性。這樣的組合不僅能減少儲存成本,還能確保檔案治理符合企業級需求,讓整個會員檔案系統在長期營運中更穩定、更高效。


上一篇
Day 20 檔案分享功能:限時連結 x 權限管理 API 設計
下一篇
Day 22 活動通知自動化:SES 打造客製化 Email 通知
系列文
從一個網站的誕生,看懂 AWS 架構與自動化的全流程!24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言