DEV Community

Cover image for Send error event of an Lambda function to SNS Topic
Danh Hoang Hieu Nghi
Danh Hoang Hieu Nghi

Posted on

Send error event of an Lambda function to SNS Topic

AWS Lambda Async Failure Destination: Gửi lỗi Lambda sang Amazon SNS ErrorTopic

Khi làm việc với AWS Lambda asynchronous invocation, một vấn đề rất thường gặp là: function xử lý message bị lỗi, nhưng mình cần một nơi tập trung để nhận thông báo lỗi và debug nhanh.

Trong bài lab này, chúng ta sẽ dựng một flow đơn giản:

Amazon SNS InputTopic
        ↓
AWS Lambda ProcessMessages
        ↓ nếu xử lý thất bại
Amazon SNS ErrorTopic
        ↓
Email notification
Enter fullscreen mode Exit fullscreen mode

Mục tiêu là cấu hình failure destination cho Lambda function ProcessMessages, để khi function xử lý message thất bại, Lambda tự động gửi failure record sang SNS topic ErrorTopic.


Bài toán cần giải quyết

Giả sử bạn có một Lambda function tên là ProcessMessages.

Function này được invoke asynchronously khi có message được publish vào Amazon SNS topic tên là InputTopic.

Yêu cầu đặt ra:

Khi Lambda ProcessMessages xử lý message thất bại, hệ thống phải gửi thông báo lỗi đến SNS topic ErrorTopic, sau đó SNS gửi email alert cho người quản trị.

Đây là một tình huống rất thực tế trong các hệ thống event-driven trên AWS. Thay vì để lỗi nằm im trong CloudWatch Logs, chúng ta muốn đẩy lỗi ra một kênh alert tập trung.


Vì sao dùng Lambda Failure Destination?

Với Lambda asynchronous invocation, caller không chờ Lambda xử lý xong để nhận kết quả ngay lập tức. Lambda nhận event, đưa vào hàng đợi nội bộ, rồi xử lý sau.

Nếu function lỗi, Lambda có thể retry. Khi event vẫn thất bại sau các lần retry, Lambda có thể gửi failure record đến một destination, ví dụ:

  • Amazon SNS topic
  • Amazon SQS queue
  • Lambda function khác
  • Amazon EventBridge

Trong bài lab này, chúng ta dùng Amazon SNS ErrorTopic làm failure destination.

Điểm quan trọng là:

SNS InputTopic không tự biết Lambda fail.
Lambda mới là nơi biết xử lý thành công hay thất bại.
Enter fullscreen mode Exit fullscreen mode

Vì vậy, cách đúng là cấu hình Destination on failure trên Lambda, trỏ đến ErrorTopic.


Kiến trúc lab

Trong lab này, chúng ta sẽ tạo và cấu hình các thành phần sau:

  1. Tạo SNS topic InputTopic
  2. Tạo SNS topic ErrorTopic
  3. Subscribe email vào ErrorTopic
  4. Tạo Lambda function ProcessMessages
  5. Gắn InputTopic làm trigger cho Lambda
  6. Viết code Lambda cố tình throw error
  7. Cấu hình Lambda async failure destination trỏ về ErrorTopic
  8. Publish message vào InputTopic
  9. Kiểm tra email alert từ ErrorTopic

Hands-on Lab bằng AWS Console

Phần này dùng AWS Console để thao tác trực tiếp. Bạn có thể làm nhanh trong tài khoản AWS cá nhân.


Bước 1: Tạo SNS topic InputTopic

Vào AWS Console, mở dịch vụ Amazon SNS.

Đi theo đường dẫn:

Amazon SNS → Topics → Create topic
Enter fullscreen mode Exit fullscreen mode

Chọn cấu hình:

Type: Standard
Name: InputTopic
Enter fullscreen mode Exit fullscreen mode

Sau đó bấm:

Create topic
Enter fullscreen mode Exit fullscreen mode

Sau khi tạo xong, lưu lại ARN của topic. Ví dụ:

arn:aws:sns:ap-southeast-1:123456789012:InputTopic
Enter fullscreen mode Exit fullscreen mode

Create Topic

Created the Topic


Bước 2: Tạo SNS topic ErrorTopic

Tiếp tục tạo topic thứ hai để nhận failure notification.

Vào:

Amazon SNS → Topics → Create topic
Enter fullscreen mode Exit fullscreen mode

Chọn:

Type: Standard
Name: ErrorTopic
Enter fullscreen mode Exit fullscreen mode

Bấm:

Create topic
Enter fullscreen mode Exit fullscreen mode

ErrorTopic sẽ là nơi nhận failure record từ Lambda khi ProcessMessages xử lý message thất bại.


Bước 3: Subscribe email vào ErrorTopic

Vào topic ErrorTopic, chọn:

Subscriptions → Create subscription
Enter fullscreen mode Exit fullscreen mode

Cấu hình subscription:

Protocol: Email
Endpoint: email của bạn
Enter fullscreen mode Exit fullscreen mode

Ví dụ:

hieunghiwork123@gmail.com
Enter fullscreen mode Exit fullscreen mode

Sau đó bấm:

Create subscription
Enter fullscreen mode Exit fullscreen mode

Create subscription

Sau khi tạo subscription, mở hộp thư email và bấm Confirm subscription.

email confirmation

Lưu ý: email xác nhận có thể nằm trong thư mục Spam hoặc Promotions. Nếu subscription chưa được confirm, SNS sẽ không gửi email alert cho bạn.


Bước 4: Tạo Lambda function ProcessMessages

Vào AWS Lambda:

AWS Lambda → Functions → Create function
Enter fullscreen mode Exit fullscreen mode

Chọn:

Author from scratch
Function name: ProcessMessages
Runtime: Python 3.12
Architecture: x86_64
Enter fullscreen mode Exit fullscreen mode

Sau đó bấm:

Create function
Enter fullscreen mode Exit fullscreen mode

Lambda Configuration


Bước 5: Viết code Lambda cố tình fail

Để test failure destination, chúng ta sẽ viết Lambda luôn throw exception.

Trong Lambda code editor, thay code bằng:

import json

def lambda_handler(event, context):
    print("Received event:")
    print(json.dumps(event))

    # Giả lập xử lý message thất bại
    raise Exception("Simulated processing failure from ProcessMessages")
Enter fullscreen mode Exit fullscreen mode

Sau đó bấm:

Deploy
Enter fullscreen mode Exit fullscreen mode

Lambda Code UI VSC

Ý nghĩa của đoạn code này:

  • Lambda nhận event từ InputTopic
  • In event ra CloudWatch Logs
  • Cố tình throw exception
  • Lambda async invocation retry
  • Khi retry thất bại hết, Lambda gửi failure record sang ErrorTopic

Đây là cách test đơn giản để kiểm tra cơ chế Lambda async failure destination.


Bước 6: Gắn InputTopic làm trigger cho Lambda

Trong Lambda ProcessMessages, vào tab:

Configuration → Triggers → Add trigger
Enter fullscreen mode Exit fullscreen mode

Trigger

Chọn:

Source: SNS
SNS topic: InputTopic
Enter fullscreen mode Exit fullscreen mode

Sau đó bấm:

Add
Enter fullscreen mode Exit fullscreen mode

Lúc này flow đầu vào đã có:

InputTopic → ProcessMessages
Enter fullscreen mode Exit fullscreen mode

Từ giờ, mỗi khi bạn publish message vào InputTopic, SNS sẽ invoke Lambda ProcessMessages.


Bước 7: Cấu hình Failure Destination cho Lambda

Đây là phần quan trọng nhất của lab.

Trong Lambda ProcessMessages, vào:

Configuration → Destinations → Add destination
Enter fullscreen mode Exit fullscreen mode

Chọn:

Source: Asynchronous invocation
Condition: On failure
Destination type: SNS topic
Destination: ErrorTopic
Enter fullscreen mode Exit fullscreen mode

Hoặc nếu giao diện AWS Console của bạn hiển thị theo cách khác, có thể đi theo đường dẫn:

Configuration → Asynchronous invocation → Edit
Destination on failure → SNS topic → ErrorTopic
Enter fullscreen mode Exit fullscreen mode

Sau đó bấm:

Save
Enter fullscreen mode Exit fullscreen mode

Sau bước này, khi Lambda xử lý event thất bại sau các lần retry, Lambda sẽ gửi failure record sang SNS topic ErrorTopic.


Bước 8: Kiểm tra IAM permission

Để Lambda gửi được message sang SNS topic ErrorTopic, execution role của Lambda cần quyền sns:Publish.

Policy tối thiểu có dạng:

{
  "Effect": "Allow",
  "Action": "sns:Publish",
  "Resource": "arn:aws:sns:REGION:ACCOUNT_ID:ErrorTopic"
}
Enter fullscreen mode Exit fullscreen mode

Ví dụ:

{
  "Effect": "Allow",
  "Action": "sns:Publish",
  "Resource": "arn:aws:sns:ap-southeast-1:123456789012:ErrorTopic"
}
Enter fullscreen mode Exit fullscreen mode

Nếu thiếu quyền này, Lambda có thể xử lý fail đúng như mong đợi nhưng không gửi được failure record sang ErrorTopic.

Khi debug, bạn có thể kiểm tra metric:

DestinationDeliveryFailures
Enter fullscreen mode Exit fullscreen mode

Nếu metric này tăng, thường là do permission, ARN, region hoặc destination config có vấn đề.


Bước 9: Publish message vào InputTopic để test

Vào SNS topic InputTopic, chọn:

Publish message
Enter fullscreen mode Exit fullscreen mode

Nhập subject:

Test Lambda Failure
Enter fullscreen mode Exit fullscreen mode

Nhập message body:

{
  "orderId": "12345",
  "action": "process"
}
Enter fullscreen mode Exit fullscreen mode

Sau đó bấm:

Publish message
Enter fullscreen mode Exit fullscreen mode

Khi đó flow sẽ chạy như sau:

InputTopic nhận message
→ SNS invoke Lambda ProcessMessages
→ Lambda throw exception
→ Lambda retry async invocation
→ Sau khi fail hết retry
→ Lambda gửi failure record sang ErrorTopic
→ ErrorTopic gửi email alert
Enter fullscreen mode Exit fullscreen mode

Bước 10: Kiểm tra CloudWatch Logs

Vào CloudWatch:

CloudWatch → Log groups
Enter fullscreen mode Exit fullscreen mode

Tìm log group:

/aws/lambda/ProcessMessages
Enter fullscreen mode Exit fullscreen mode

Bạn sẽ thấy log tương tự:

Received event:
...
Exception: Simulated processing failure from ProcessMessages
Enter fullscreen mode Exit fullscreen mode

Điều này chứng minh Lambda đã nhận event từ SNS nhưng xử lý thất bại.


Bước 11: Kiểm tra email từ ErrorTopic

Sau một lúc, bạn sẽ nhận được email từ SNS ErrorTopic.

Nội dung email thường chứa failure record từ Lambda. Một số field quan trọng gồm:

Field Ý nghĩa
requestContext Thông tin về request Lambda async invocation
condition Lý do event được gửi sang failure destination
approximateInvokeCount Số lần Lambda đã cố invoke event
requestPayload Event gốc được gửi vào Lambda
responseContext Thông tin response sau khi Lambda xử lý
functionError Loại lỗi của function
responsePayload Error message và stack trace

Ví dụ khi bạn thấy:

{
  "condition": "RetriesExhausted",
  "approximateInvokeCount": 3,
  "functionError": "Unhandled"
}
Enter fullscreen mode Exit fullscreen mode

Điều này nghĩa là Lambda đã xử lý thất bại sau toàn bộ retry attempts. Mặc định, bạn có thể thấy tổng cộng khoảng 3 lần invoke: 1 lần đầu và 2 lần retry.


Vì sao email alert có thể đến hơi chậm?

Đây là điểm rất dễ gây nhầm khi mới làm lab.

Với asynchronous invocation, Lambda không gửi failure record sang destination ngay sau lần fail đầu tiên. Lambda sẽ retry trước. Khi event fail hết các lần retry, lúc đó Lambda mới gửi record sang ErrorTopic.

Vì vậy nếu bạn thấy Lambda được invoke 2 lần nhưng chưa nhận mail, có thể đơn giản là Lambda chưa retry hết.

Nếu muốn test nhanh hơn, có thể chỉnh:

Lambda → Configuration → Asynchronous invocation → Edit
Retry attempts: 0
Enter fullscreen mode Exit fullscreen mode

Sau đó publish message mới vào InputTopic. Khi retry attempts là 0, failure destination sẽ được kích hoạt nhanh hơn.


Vì sao đây là đáp án đúng trong AWS Exam?

Câu hỏi AWS exam thường đưa ra tình huống:

  • Lambda được invoke asynchronously
  • Lambda xử lý message thất bại
  • Cần gửi notification đến SNS topic
  • Có sẵn ErrorTopic để nhận lỗi

Trong trường hợp này, giải pháp đúng là:

Configure a failure destination for the Lambda function.
Specify the ARN of the ErrorTopic SNS topic as the destination ARN.
Enter fullscreen mode Exit fullscreen mode

Lý do: failure destination là cơ chế native của Lambda dành cho asynchronous invocation failure.


Vì sao không dùng SNS filter policy?

Một nhầm lẫn phổ biến là nghĩ rằng có thể dùng SNS filter policy để bắt lỗi Lambda.

Thực tế, SNS filter policy chỉ lọc message đã được publish vào SNS topic trước khi gửi đến subscriber. Nó không tự biết Lambda function xử lý thành công hay thất bại.

Flow sai sẽ là:

ErrorTopic → ProcessMessages
Enter fullscreen mode Exit fullscreen mode

Trong khi yêu cầu đúng là:

ProcessMessages fail → ErrorTopic
Enter fullscreen mode Exit fullscreen mode

Vì vậy, không dùng SNS filter policy cho bài toán này.


Vì sao không dùng SNS delivery policy?

SNS delivery policy dùng để kiểm soát cách SNS retry khi gửi message đến subscriber. Nó không phải cơ chế để Lambda báo lỗi xử lý message.

Nói ngắn gọn:

SNS delivery policy = SNS gửi message ra subscriber như thế nào
Lambda failure destination = Lambda fail thì gửi failure record đi đâu
Enter fullscreen mode Exit fullscreen mode

Bài này cần cơ chế thứ hai.


Dọn dẹp tài nguyên sau lab

Sau khi test xong, bạn nên xóa các resource sau để tránh phát sinh chi phí hoặc làm rối tài khoản AWS:

Lambda function: ProcessMessages
SNS topic: InputTopic
SNS topic: ErrorTopic
CloudWatch log group: /aws/lambda/ProcessMessages
Enter fullscreen mode Exit fullscreen mode

Nếu không cần giữ log, vào CloudWatch và xóa log group tương ứng.


Tổng kết

Trong bài lab này, chúng ta đã cấu hình thành công flow:

SNS InputTopic
        ↓
Lambda ProcessMessages
        ↓ On failure destination
SNS ErrorTopic
        ↓
Email notification
Enter fullscreen mode Exit fullscreen mode

Đây là một pattern rất hữu ích khi xây dựng hệ thống event-driven trên AWS. Thay vì chỉ xem lỗi trong CloudWatch Logs, bạn có thể đẩy failure record sang SNS để gửi email, tích hợp với hệ thống alert, hoặc fan-out sang nhiều subscriber khác.

Keyword cần nhớ cho AWS Exam:

Lambda asynchronous invocation
Failure destination
Destination on failure
SNS ErrorTopic
RetriesExhausted
Enter fullscreen mode Exit fullscreen mode

Khi đề bài nói Lambda async invocation thất bại và cần gửi thông báo sang SNS topic, hãy nghĩ ngay đến:

Lambda async failure destination
Enter fullscreen mode Exit fullscreen mode

Top comments (0)