Debugging AWS Lambda với LocalStack

Debugging AWS Lambda với LocalStack

LocalStack là gì?

LocalStack là một công cụ phát triển phần mềm mã nguồn mở giúp bạn triển khai và chạy ứng dụng trên môi trường đám mây giả lập trên máy tính cá nhân hoặc máy chủ của bạn. Nó cung cấp một bản sao của nhiều dịch vụ đám mây phổ biến, chẳng hạn như Amazon S3, AWS Lambda, DynamoDB, và nhiều dịch vụ khác. Điều này cho phép bạn phát triển, kiểm tra và debug ứng dụng của bạn mà không cần phải kết nối đến một môi trường đám mây thực sự.

Cài đặt

Cài đặt LocalStack

Làm theo hướng dẫn ở link sau để cài đặt LocalStack:

https://docs.localstack.cloud/getting-started/installation/

Cài đặt Docker

Làm theo hướng dẫn ở link sau để cài đặt Docker:

https://docs.docker.com/engine/install/

Cài đặt AWS CLI

Làm theo hướng dẫn ở link sau để cài đặt AWS CLI và cấu hình profile cho môi trường local:

https://docs.localstack.cloud/user-guide/integrations/aws-cli/#aws-cli

Thiết lập LocalStack

Tạo file docker-compose.yml

Chúng ta sẽ bắt đầu LocalStack với thiết lập Docker-Compose. Tạo một file mới có tên docker-compose.yml và thêm cấu hình sau:

version: "3.8"

services:
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"  # Name of the container to be used
    image: localstack/localstack:latest  # Docker image for LocalStack, latest version
    ports:
      - "127.0.0.1:4566:4566"            # Port for accessing LocalStack Gateway from the local machine
      - "127.0.0.1:4510-4559:4510-4559"  # Port range for external services
    environment:
      - DEBUG=1  # Enable Debug mode in LocalStack
      - LAMBDA_REMOTE_DOCKER=0  # Turn off remote Docker usage for Lambda
      - LAMBDA_DOCKER_FLAGS=-e NODE_OPTIONS=--inspect-brk=0.0.0.0:9229 -p 9229:9229  # Exposes port 9229 for debugging the Lambda handler code.
      - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-}  # Lambda execution type (if defined)
      - DOCKER_HOST=unix:///var/run/docker.sock  # Link to Docker via Docker socket
    volumes:
      - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"  # Mount point for LocalStack data directory
      - "/var/run/docker.sock:/var/run/docker.sock"  # Mount Docker socket to access Docker from the LocalStack container
Ngoài ra để xem thêm các cấu hình khác của LocalStack bạn có thể tham khảo link sau:

Khởi động LocalStack với Docker

Chúng ta sẽ chạy lệnh sau để khởi động LocalStack:

docker compose up -d

Sau khi chạy lệnh trên thì chúng ta thấy Docker Container đã được Running

Và đã khởi động thành công LocalStack

Tạo file launch.json

Chúng ta tạo một file .vscode/launch.json và thêm cấu hình sau:

{
  "version": "0.2.0",
  "configurations": [
    {
      "address": "127.0.0.1",
      "localRoot": "${workspaceFolder}",
      "name": "Attach to Remote Node.js",
      "port": 9229,
      "remoteRoot": "/var/task/",
      "request": "attach",
      "type": "node",
      "preLaunchTask": "Wait Remote Debugger Server"
    },
  ]
}

Tạo file tasks.json

Chúng ta tạo một file .vscode/tasks.json và thêm cấu hình sau:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Wait Remote Debugger Server",
      "type": "shell",
      "command": "while [[ -z $(docker ps | grep :9229) ]]; do sleep 1; done; sleep 1;"
    }
  ]
}

Lưu ý: Đoạn code trên chỉ thực thi trên Linux và macOS. Nếu bạn đang dùng Windows thì sẽ thực hiện như sau:

Tạo file .vscode/tasks.json:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Wait Remote Debugger Server",
      "type": "shell",
      "command": "powershell",
      "args": [
        ".\\.vscode\\wait-debugger.ps1"
      ]
    }
  ]
}
Tạo file .vscode/wait-debugger.ps1:
while (-not (docker ps | Select-String ":9229")) {
  Start-Sleep -Seconds 1
}
Start-Sleep -Seconds 1

Tạo file function.ts

Trong ví dụ này, chúng ta sẽ tạo file function.ts chứa code hàm Lambda bằng Node.js và TypeScript để kiểm tra debug:

export const  handler = async (event: any) =>  {
  const response = {
    statusCode: 200,
    body: "hello word",
  };
  return response;
};

Tạo Lambda Function trên LocalStack

Để tạo Lambda Function trên LocalStack chúng ta sử dụng câu lệnh sau:

aws --endpoint-url=http://localhost:4566 lambda create-function \
--function-name localstack-lambda-function \
--code S3Bucket="hot-reload",S3Key="$(pwd)/" \
--handler function.handler \
--runtime nodejs18.x \
--timeout 120 \
--role arn:aws:iam::000000000000:role/lambda-role

Sau khi chạy lệnh trên thì Lambda Function đã được tạo thành công trên LocalStack

Thực hiện Debugging Lambda Function

Trong VS Code bạn có thể debug bằng cách đặt các breakpoint chỗ đoạn code cần debug và nhấn F5 để chạy

Sau đó thực thi Lambda Function bằng câu lệnh sau:

aws --endpoint-url=http://localhost:4566 lambda invoke \
--function-name localstack-lambda-function lambda.log \
--cli-binary-format raw-in-base64-out \
--payload '{"hello":"world"}'

Sau khi chạy lệnh trên thì bạn đã debug thành công

Thực hiện Debugging Lambda Function với Amazon S3 để trigger AWS Lambda khi upload file

Tạo bucket trên Amazon S3

Để tạo bucket trên Amazon S3 chúng ta sử dụng câu lệnh sau:

aws s3api create-bucket --bucket local-stack-bucket --create-bucket-configuration LocationConstraint=ap-northeast-1 --endpoint-url=http://localhost:4566

Trong đó:

+ local-stack-bucket: là tên của bucket

Cấu hình Amazon S3 trigger đến Lambda Function

Để trigger Lambda Function khi upload file lên Amazon S3 chúng ta sử dụng câu lệnh sau:

aws --endpoint-url=http://localhost:4566 s3api put-bucket-notification-configuration \
    --bucket local-stack-bucket \
    --notification-configuration '{
        "LambdaFunctionConfigurations": [
          {
            "Id": "1", 
            "LambdaFunctionArn": "arn:aws:lambda:ap-northeast-1:000000000000:function:localstack-lambda-function",
            "Events": ["s3:ObjectCreated:*"]
          }
        ]
    }'

Trong đó:

+ local-stack-bucket: là tên của bucket cần cấu hình

+ LambdaFunctionArn: là Arn của Lambda Function cần trigger

+ Events: là sự kiện trên Amazon S3 để trigger Lambda Function

Tiến hành debug Lambda Function

Trong VS Code bạn có thể debug bằng cách đặt các breakpoint chỗ đoạn code cần debug và nhấn F5 để chạy

Sau đó tiến hành upload file lên Amazon S3 bucket trên LocalStack cloud

 

Sau khi upload file thì bạn đã debug thành công

Các mặt hạn chế của LocalStack

Hỗ Trợ Giới Hạn Cho Dịch Vụ AWS: LocalStack cung cấp giả lập cho một số dịch vụ quan trọng như S3, DynamoDB, Lambda, và SQS. Tuy nhiên, không phải tất cả các dịch vụ AWS đều được hỗ trợ, và một số dịch vụ có thể không có hoặc chỉ được triển khai với một số tính năng cơ bản. Điều này có thể là một rắc rối nếu ứng dụng của bạn phụ thuộc vào các dịch vụ không được hỗ trợ.

Thiếu Tính Năng: Mặc dù LocalStack giúp mô phỏng các dịch vụ, nhưng không phải tất cả các tính năng của chúng được triển khai. Các tùy chọn cấu hình có thể bị giới hạn, làm giảm sự tương thích giữa môi trường phát triển local và môi trường thực tế trên AWS.

Khả Năng Mở Rộng Hạn Chế: LocalStack không thiết kế để mở rộng mạnh mẽ như môi trường AWS. Nếu bạn đang làm việc trên các dự án lớn với quy mô lớn, việc kiểm thử và phát triển trong môi trường local có thể không phản ánh đúng thực tế trên AWS.

Sự Chậm Trễ: Do sự giả lập và cố gắng sao chép các dịch vụ AWS, LocalStack có thể có sự chậm trễ so với việc sử dụng các dịch vụ thực tế. Điều này có thể làm giảm hiệu suất và làm chậm quá trình phát triển và kiểm thử.

Cập Nhật Chậm: LocalStack có thể không cập nhật nhanh chóng theo các phiên bản mới của dịch vụ AWS. Điều này có thể tạo ra sự không đồng bộ khi cần sử dụng các tính năng mới hoặc khi có sự thay đổi trong API của AWS.

Kết luận

Về việc sử dụng LocalStack giúp chúng ta phát triển và debug Lambda Function, cũng như các dịch vụ AWS khác một cách hiệu quả trên môi trường local. Nó giúp đảm bảo tích hợp và hoạt động đúng trước khi triển khai lên AWS thực tế, tiết kiệm thời gian, chi phí và giảm tác động đến tài khoản AWS thực tế của bạn trong quá trình phát triển.

Tài liệu tham khảo

https://docs.localstack.cloud/