Lambda function chỉnh kích thước ảnh

Trong bước này, chúng ta sẽ tạo một hàm Lambda tự động chỉnh kích thước ảnh sau khi ảnh được tải lên S3. Khi người dùng tải ảnh bìa sách lên thông qua hàm book_create, hàm ImageResize này sẽ được kích hoạt bởi sự kiện S3, chỉnh kích thước ảnh theo kích thước chỉ định, và lưu kết quả vào bucket BookImageResizeShop để phục vụ cho frontend.

Cách hoạt động

  1. Người dùng tải ảnh lên → lưu trữ trong bucket BookImageShop
  2. S3 kích hoạt hàm Lambda resize_image (s3:ObjectCreated:*)
  3. Hàm đọc ảnh gốc, chỉnh kích thước thành 200×280px, và lưu phiên bản đã resize vào bucket BookImageResizeShop
  4. Frontend đọc ảnh sách từ resize bucket

Chỉnh sửa SAM Template

  1. Mở tệp template.yaml trong thư mục fcaj-book-shop.

  2. Đầu tiên, thêm các tham số widthheight vào phần Parameters. Các tham số này xác định kích thước đích cho ảnh đã resize:

    width:
      Type: String
      Default: 200px
    
    height:
      Type: String
      Default: 280px
    

    Thêm tham số width và height

  3. Tiếp theo, thêm tài nguyên hàm ImageResize vào phần Resources:

    ImageResize:
      Type: AWS::Serverless::Function
      Properties:
        CodeUri: fcaj-book-shop/resize_image/function.zip
        PackageType: Zip
        Handler: index.handler
        Runtime: nodejs22.x
        FunctionName: resize_image
        Architectures:
          - x86_64
        Policies:
          - Statement:
              - Sid: ResizeUploadImage
                Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:PutObject
                  - s3:DeleteObject
                Resource:
                  - !Sub "arn:aws:s3:::${bookImageShopBucketName}/*"
                  - !Sub "arn:aws:s3:::${bookImageResizeShopBucketName}/*"
        Events:
          ResizeImage:
            Type: S3
            Properties:
              Bucket: !Ref BookImageShop
              Events: s3:ObjectCreated:*
        Environment:
          Variables:
            WIDTH: !Ref width
            HEIGHT: !Ref height
            DES_BUCKET: !Ref BookImageResizeShop
    

    Tài nguyên hàm ImageResize

Hàm này khác với các hàm Lambda Python mà chúng ta đã tạo trước đó:

  • Sử dụng runtime Node.js 22.x (không phải Python)
  • Code được triển khai dưới dạng tệp ZIP đóng gói sẵn (PackageType: Zip)
  • Được kích hoạt bởi sự kiện S3 (s3:ObjectCreated:*) thay vì được gọi trực tiếp qua API
  1. Cuối cùng, thêm tài nguyên ImageResizeInvokePermission để cấp quyền cho bucket S3 BookImageShop kích hoạt hàm Lambda này:

    ImageResizeInvokePermission:
      Type: "AWS::Lambda::Permission"
      Properties:
        FunctionName: !Ref ImageResize
        Action: "lambda:InvokeFunction"
        Principal: "s3.amazonaws.com"
        SourceAccount: !Sub ${AWS::AccountId}
        SourceArn: !GetAtt BookImageShop.Arn
    

    Tài nguyên ImageResizeInvokePermission

Nếu bạn tạo tên bucket S3 khác với tên trong bài workshop, hãy kiểm tra và cập nhật các Policies > Resource ARNs và Environment Variables của hàm ImageResize cho phù hợp với tên bucket của bạn.

Chuẩn bị mã nguồn

  1. Cấu trúc thư mục sẽ như sau:

    fcaj-book-shop
    ├── fcaj-book-shop
    │   ├── books_list
    │   │   └── books_list.py
    │   ├── book_create
    │   │   ├── book_create.py
    │   │   └── requirements.txt
    │   ├── book_delete
    │   │   └── book_delete.py
    │   └── resize_image
    │       └── function.zip
    └── template.yaml
    
    • Tạo thư mục resize_image trong thư mục fcaj-book-shop/fcaj-book-shop/.

    • Tải tệp function.zip bên dưới và đặt vào thư mục resize_image:

    • Tải tệp function.zip tại đây: function.zip

Build và Deploy

  1. Chạy các lệnh sau để validate và build SAM template:

    sam validate
    sam build
    

    SAM Validate và Build

  2. Triển khai stack đã cập nhật:

    sam deploy
    

    Changeset sẽ hiển thị các tài nguyên mới:

    • ImageResizeRole (AWS::IAM::Role)
    • ImageResize (AWS::Lambda::Function)
    • ImageResizeInvokePermission (AWS::Lambda::Permission)
    • ImageResizeResizeImagePermission (AWS::Lambda::Permission)
    • BookImageShop (AWS::S3::Bucket) - Modify để thêm S3 event notification

    Nhập y để xác nhận triển khai.

    SAM Deploy - Changeset

  3. Chờ quá trình triển khai hoàn tất. Bạn sẽ thấy thông báo Successfully created/updated stack.

    Deploy hoàn tất

Kiểm tra trên AWS Console

  1. Mở Lambda console. Bạn sẽ thấy bốn hàm: books_list, book_create, book_deleteresize_image.

    Lambda Functions

  2. Nhấp vào hàm resize_image. Xem phần Code source — bạn sẽ thấy tệp index.js với logic chỉnh kích thước ảnh sử dụng thư viện sharp.

    Code Source

  3. Xem phần Function overview. Chú ý S3 trigger ở phía bên trái — điều này xác nhận rằng hàm được kích hoạt tự động bởi sự kiện S3.

    Function Overview với S3 trigger

  4. Nhấp vào tab Configuration, sau đó chọn Triggers từ menu bên trái. Nhấp Details để mở rộng thông tin trigger. Xác nhận:

    • Bucket arn: arn:aws:s3:::book-image-shop-by-tranvix
    • Event types: s3:ObjectCreated:*
    • Service principal: s3.amazonaws.com

    Chi tiết S3 Trigger

  5. Chọn Environment variables từ menu bên trái. Xác nhận 3 biến môi trường:

    • DES_BUCKET = book-image-resize-shop-by-tranvix
    • HEIGHT = 280px
    • WIDTH = 200px

    Environment Variables

  6. Chọn Permissions từ menu bên trái. Nhấp vào tên execution role (ví dụ: fcaj-book-shop-ImageResizeRole-...).

    Permissions - Execution Role

  7. Tại trang IAM Role, kiểm tra phần Permissions policies. Bạn sẽ thấy:

    • AWSLambdaBasicExecutionRole (AWS managed) - cho CloudWatch Logs
    • ImageResizeRolePolicy0 (Customer inline) - policy tùy chỉnh mà chúng ta đã định nghĩa

    IAM Role Permissions

  8. Nhấp vào ImageResizeRolePolicy0 để mở rộng. Xem chi tiết policy JSON cấp quyền s3:GetObject, s3:PutObjects3:DeleteObject trên cả hai bucket image shop và resize shop.

    ImageResizeRolePolicy0 JSON