iT邦幫忙

2025 iThome 鐵人賽

DAY 14
0
Build on AWS

動漫宅的 30 天 AWS Lakehouse 修行日誌系列 第 14

DAY14 雲端基礎章-S3、Lambda、EventBridge 實作篇

  • 分享至 

  • xImage
  •  

簡介

DAY12 雲端基礎章-S3 Data Lakehouse 儲存結構設計 中我們介紹了本次將要建立的 S3 Data Lake 儲存架構,並於 DAY13 雲端基礎章-Lambda、EventBridge 概念篇 中,接續了解 Lambda 與 EventBridge 如何協同運作,今天我們就來動手實作:

當檔案上傳到 S3 Bucket 時,由 EventBridge 偵測事件並觸發 Lambda,自動在 S3 建立資料夾並重新命名檔案後存放。

這樣的設計可以讓我們:

  • 自動化檔案歸檔流程
  • 保持資料湖中檔案命名規範一致
  • 減少人工整理與錯誤風險

建立 S3 Bucket

首先先來看看我們 Day12 的設計,在 S3 的設計上,我們需要建立:

  • 一個名為 anime-lake 的 S3 Bucket
  • 建立一個 Bronze Folder
  • 接著再建立 animesratings 等兩個子資料夾

https://ithelp.ithome.com.tw/upload/images/20250928/201634436tjvsWbKbz.png

Step1:首先我們先登入 DE 權限的帳號 (Andy),接著進入到 S3 的儲存佇體頁面點選「建立儲存佇體」
https://ithelp.ithome.com.tw/upload/images/20250928/20163443wL3h9vfnbO.png

Step2:接著我們先確認:

  1. 這邊是台北區域
  2. 接著輸入 Bucket Name
  3. 物件擁有權選擇「存取控制清單 (ACL) 已停用」的選項,將所有權指定為此帳戶擁有

https://ithelp.ithome.com.tw/upload/images/20250928/20163443DzefQ7scra.png

Step3:接著往下設定,首先我們要設定封鎖公開存取的權限,基本上由於安全的考量,都會選擇預設「封鎖所有公開存取權」來避免 S3 Bucket 被其他外人瀏覽。再來我們先將「儲存佇體版本控制」做關閉,因為目前開起後就會開始針對資料的異動做版控,等於每次有檔案更新時,S3 會直接儲存一個新檔案,這個版控是需要額外收費的

https://ithelp.ithome.com.tw/upload/images/20250928/20163443RDNbEzWYRq.png

Step4:最後是要設定 S3 Bucket 的加密類型,這邊我們直接選擇預設的 SSE-S3 加密即可,並「啟用」儲存佇體金鑰(預設),然後點選「建立儲存佇體」

https://ithelp.ithome.com.tw/upload/images/20250928/2016344327wiqVVfPV.png

Step5:然後會預設跳轉回 S3 Bucket 的頁面,等待約 30 ~ 60 秒的建立時間後,會自動跳出剛剛建立的 S3 Bucket,即完成建立
https://ithelp.ithome.com.tw/upload/images/20250928/2016344349Qojz113O.png

Step6:接著我們要來建立 Bronze Folder,我們先進入 anime-lake 中,並點選「建立資料夾」
https://ithelp.ithome.com.tw/upload/images/20250928/20163443w1gHayqJBR.png

Step7:首先輸入資料夾名稱 Bronze,接著伺服器端加密我們直接使用預設「不要指定加密金鑰」即可,最後點選「建立資料夾」
https://ithelp.ithome.com.tw/upload/images/20250928/201634432YBR8Ub6eh.png

Step8:建立後會一樣會自動跳轉回剛剛的 anime-lake Bucket,可以看到成功建立的 Bronze 資料夾,接著我們直接進入該資料夾,接續建立子資料夾

https://ithelp.ithome.com.tw/upload/images/20250928/20163443PksnxguPcT.png

Step9:透過一樣的資料夾建立流程,分別建立 animesratings 等兩個子資料夾,即完成我們本次的 S3 的相關資料夾建立

https://ithelp.ithome.com.tw/upload/images/20250928/20163443RlN3cOyGCy.png

https://ithelp.ithome.com.tw/upload/images/20250928/20163443P1YAQQwxfW.png

https://ithelp.ithome.com.tw/upload/images/20250928/20163443fZAMYWNsZX.png

建立 Lambda Role

在使用 Lambda 之前,我們要建立一個 Lambda 的執行 Role

Step1:首先我們要切換使用者 Joe,才有權限建立新的 Role,並登入 IAM 服務選擇「建立角色」
https://ithelp.ithome.com.tw/upload/images/20250928/20163443GXjZgxWqG1.png

Step2:選擇 「AWS 服務」,使用案例選擇 「Lambda」,然後點選「下一步」
https://ithelp.ithome.com.tw/upload/images/20250928/201634434HtjSHLxf2.png

Step3:接著搜尋並選擇 「AWSLambda_FullAccess」、「AmazonS3FullAccess」、「AWSLambdaBasicExecutionRole」等政策,並於右下角點選下一步
https://ithelp.ithome.com.tw/upload/images/20250928/20163443ohg6ra5M0M.png

Step4:接著我們要針對此 Role 做角色命名,我這邊先命名 Full_Lambda_Role 方便管理即可
https://ithelp.ithome.com.tw/upload/images/20250928/20163443Z6dJFEl36v.png

Step5:確認政策是否選擇正確,就可以點選「建立角色」
https://ithelp.ithome.com.tw/upload/images/20250928/20163443TlPPxoDXB5.png

Step6:跳轉頁面後,確認 Full_Lambda_Role 有正常建立,我們就可以回到 Andy 的使用者開始建立 Lambda Function
https://ithelp.ithome.com.tw/upload/images/20250928/20163443a7pja7Xpks.png

建立 Lambda Function

建立完 S3 Bucket 和所需 Folder 後,我們要來撰寫 Python 的 Lambda Function 來針對每次上傳的新 CSV 檔案做一個年月日 Partition 的處理

Step1:接著我們一樣於左上方的搜尋功能尋找到 Lambda 的 Service
https://ithelp.ithome.com.tw/upload/images/20250928/201634433kdXCQCB0M.png

Step2:於 Lambda 的頁面右上角選擇「建立函數」
https://ithelp.ithome.com.tw/upload/images/20250928/20163443wFEa6UiQ0B.png

Step3:首先我們選擇 「從頭開始撰寫」,接著輸入

  • 函數名稱我們命名為 anime-lake-bronze-partition
  • 執行的程式語言我們選擇 「Python 3.13」
  • 架構選擇 x86_64(預設)

https://ithelp.ithome.com.tw/upload/images/20250928/20163443rwmtdda3S3.png

Step4:在使用 Lambda Function 時,會需要一個擁有使用 Lambda 權限的 Role,我們這邊選擇剛剛建立好的
Full_Lambda_Role 後點選「建立函數」
https://ithelp.ithome.com.tw/upload/images/20250928/201634435nBcucUdXy.png

Step5:跳轉到 anime-lake-bronze-partition 頁面後,我們將於下方程式碼頁面開始編輯 Python 腳本
https://ithelp.ithome.com.tw/upload/images/20250928/20163443nlM3jzyX7x.png

Step6:於程式編輯區塊撰寫 Python 腳本,撰寫好後,點選左邊的 「Deploy」按鈕,即完成 Lambda Function 的建立

https://ithelp.ithome.com.tw/upload/images/20250928/201634436Q30sDKhU2.png

https://ithelp.ithome.com.tw/upload/images/20250928/20163443tbFpGEQRe3.png

為本次所需之 Python Code,使用 boto3 lib 來控制 S3

import boto3
import os
import re

s3 = boto3.client("s3")

def lambda_handler(event, context):
    record = event["Records"][0]
    bucket = record["s3"]["bucket"]["name"]
    key = record["s3"]["object"]["key"]

    # 檔名 (不含路徑)
    filename = os.path.basename(key)  # e.g. animes_20250928.csv

    # 正則解析 dataset 與日期 (YYYYMMDD)
    match = re.match(r"^(animes|ratings)_(\d{8})\.csv$", filename)
    if not match:
        return {
            "statusCode": 400,
            "body": f"Unsupported file format: {filename}"
        }

    dataset, file_date_raw = match.groups()  # dataset=animes, file_date_raw=20250928

    # 轉換日期格式 YYYYMMDD → YYYY-MM-DD
    file_date = f"{file_date_raw[0:4]}-{file_date_raw[4:6]}-{file_date_raw[6:8]}"

    # 生成新 S3 路徑
    new_key = f"Bronze/{dataset}/{file_date}/{dataset}.csv"

    # 複製到新位置
    s3.copy_object(
        Bucket=bucket,
        CopySource={"Bucket": bucket, "Key": key},
        Key=new_key
    )

    # 刪除原始檔案(可選)
    s3.delete_object(Bucket=bucket, Key=key)

    return {
        "statusCode": 200,
        "body": f"File {filename} moved to {new_key}"
    }

建立 EventBridge 規則

建立完 S3 Bucket 和所需 Folder 後,我們要來建立監聽 S3 PutObject 的 Event

Step1:首先先回到 anime-lake 的頁面,然後點選下方 Menu 的 「屬性」頁籤
https://ithelp.ithome.com.tw/upload/images/20250928/20163443fRfNvnhECT.png

Step2:接著找到事件通知的區塊,點選「建立事件通知」
https://ithelp.ithome.com.tw/upload/images/20250928/20163443ZAjYwxUN5R.png

Step3:接著做設定:

  • 輸入事件名稱 bronze-file-upload-animes 我們這邊這些可以按照你好讀懂的命名方式,方面後續的管控
  • 前綴我們先選擇 Bronze/animes 作為偵測 animes 子資料夾的路徑設定
  • 尾碼我們要輸入 「.csv」的副檔名,並於事件類型選擇「PUT」這樣 S3 就只會針對 csv 的上傳做後續的觸發

https://ithelp.ithome.com.tw/upload/images/20250928/201634431FGa8iO5qr.png

Step4:接著我們將頁面往下拉,找到目的地的設定

  • 當我們判斷到有新的 CSV 檔案上傳到 S3 指定位置後,我們要觸發 Lambda Function 來完成接下來針對新檔案的後續處理動作
  • 首先選擇目的地為「Lambda 函數」
  • 指定 Lambda 函數我們選擇「從 Lambda 函數中選擇」
  • 然後選擇我們剛剛建立的 Lambda 函數 anime-lake-bronze-partition 後,點選「儲存變更」

https://ithelp.ithome.com.tw/upload/images/20250928/201634437YCmhM9L9u.png

Step5:完成後,我們回到 Lambda Function anime-lake-bronze-partition 的頁面,可以看到上方的函示概觀的區塊下方多了一個 S3 的 Pipeline,即完成了 EventBridge 觸發 Lambda 的設定

https://ithelp.ithome.com.tw/upload/images/20250928/20163443Jn8qlGFNBj.png

Step6:最後由於 EventBridge 是預設不啟動的,我們需要把調整成「啟動」,才可以正常的開始做 S3 Bucket 的 Event 偵測

https://ithelp.ithome.com.tw/upload/images/20250928/20163443WI5gH88gnu.png

https://ithelp.ithome.com.tw/upload/images/20250928/20163443sBjytqi3lj.png

接著我們還需要建立另一個資料夾 ratings 的 EventBridge,這邊我們做個小挑戰,想請讀者自己建立看看,並實際查閱是否正常運作

https://ithelp.ithome.com.tw/upload/images/20250928/201634434R3alrszJe.png

實測執行狀況

將 S3 Bucket 、Lambda、EventBridge 都建立完成後,接著我們來實測看看上傳檔案到 S3 Folder 內是否真的會自動建立新的 Partition Folder

Step1:回到 anime-lake/Bronze/animes 的頁面,並點選上傳檔案
https://ithelp.ithome.com.tw/upload/images/20250928/20163443wjYIOUw89n.png

Step2:選擇要上傳的 animes.csv 檔案後點選「上傳」
https://ithelp.ithome.com.tw/upload/images/20250928/20163443ySDHWxmRkN.png

https://ithelp.ithome.com.tw/upload/images/20250928/20163443kvpB1FDiZz.png

https://ithelp.ithome.com.tw/upload/images/20250928/20163443CcRRpB5pmj.png

Step3:接著到 anime-lake/Bronze/animes/ 查看剛剛設計好的 EventBridge 是否有正常運作,可以看到剛剛的 animes_20250928.csv 檔案變成一個 2025-09-28 的資料夾,且裡面存放了去掉日期的 animes.csv 檔案,代表我們的 EventBridge 和 Lambda 是有正常運作的,即完成了整個 S3 Event 觸發 Lambda 的設定

https://ithelp.ithome.com.tw/upload/images/20250928/20163443HH2447tWh1.png

https://ithelp.ithome.com.tw/upload/images/20250928/20163443Xb3GlmcZeU.png

總結與建議

透過 S3 + EventBridge + Lambda,我們建立了一個自動檔案歸檔流程。

這種設計在資料湖專案中非常常見,例如:

  • 每日匯入 CSV/JSON 檔案
  • 自動依日期/批次分類
  • 確保命名規範一致

可需根據不同的場景依照需求設定相關的 Pipeline,才能最佳的解決自己的需求

下篇預告

下篇我們將進入下一個章節 「Day15 淬鍊之章-Glue 概念篇」,一起來了解一下 AWS 的 ETL 服務 Glue。

參考資料


上一篇
DAY13 雲端基礎章-Lambda、EventBridge 概念篇
下一篇
DAY15 淬鍊之章-Glue 概念篇
系列文
動漫宅的 30 天 AWS Lakehouse 修行日誌19
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言