[英]Need help configuring DLQ for Lambda triggered by SNS
如果我的 Lambda 失敗,我想收到一個 email。 Lambda 是通過 SNS 觸發的(由 SES 觸發)。
當我發布到 SNS 主題時,Lambda 運行並由於缺少 package 而拋出錯誤(用於測試)。我從控制台日志中看到 Lambda 運行了 3 次。
我有一個 SQS 隊列附加到 SNS 主題訂閱(觸發 lambda)的Redrive policy (dead-letter queue)
)。
{
"deadLetterTargetArn": "arn:aws:sqs:us-east-1:123456789012:myproj-sns-topic-dlq"
}
我測試過,但沒有任何效果。 我在 AWS 控制台中注意到 SNS 主題訂閱的警告:
死信隊列(重新驅動策略)權限 指定為訂閱死信隊列(重新驅動策略)的 Amazon SQS 隊列不允許從主題傳送。 要允許 Amazon SNS 主題向 Amazon SQS 隊列發送消息,您必須創建 Amazon SQS 隊列策略。
按照將Amazon SQS 隊列訂閱到 Amazon SNS 主題的步驟,我將第二條語句添加到我的 SQS 隊列的Access policy
中:
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__owner_statement",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "SQS:*",
"Resource": "arn:aws:sqs:us-east-1:123456789012:myproj-sns-topic-dlq"
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:123456789012:myproj-sns-topic-dlq",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:sns:us-east-1:123456789012:myproj-snstopic"
}
}
}
]
}
Principal
是{"Service": "sns.amazonaws.com"}
,但這會導致 AWS 控制台中出現一條警告,指出它無法測試權限。 無論如何我都測試過,但沒有用。 (Lambda 運行了 3 次,但 DLQ 中沒有任何內容。)
我現在將 Principal 設置為 *(根據上面的代碼片段)。 這消除了控制台中的警告,但仍然無法正常工作。
我的目標是在 Lambda 失敗后將事件放入 SQS DLQ。 我在那個隊列上有一個警報,它會通過 email 通知我...
編輯:添加缺失條件
根據這篇文章,您可以使用 CloudWatch 日志過濾器來解析 Lambda function 的日志,並獲得 email 通知。
要實施此解決方案,您必須創建以下內容:
正如@fedonev 所指出的,當無法傳遞事件時,將使用 SNS 訂閱的(對於 lambda)DLQ。 如果事件已傳送(但 Lambda 失敗),您可以使用 Lambda 的異步事件 DLQ 或連接 Lambda 的“失敗時”目標。
我正在使用 AWS Amplify 並決定使用 Lambda 的“異步”DLQ 而不是 lambda 目標。
第 1 步 - 添加自定義類別以添加:
並“輸出”Lambda 所需的 SQS 隊列的 ARN。
第 2 步 - 將“DeadLetterConfig”添加到 Lambda,將失敗推送到上述隊列中。
amplify add custom
名稱:LambdaAlarm
文件: amplify/backend/custom/LambdaAlarm/LambdaAlarm-cloudformation-template.json
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"env": {
"Type": "String"
}
},
"Resources": {
"SQSDLQ": {
"Type": "AWS::SQS::Queue",
"Properties": {
"QueueName": {
"Fn::Join": [
"",
[
"myproject-lambdafailed-dlq",
{
"Fn::Select": [
3,
{
"Fn::Split": [
"-",
{
"Ref": "AWS::StackName"
}
]
}
]
},
"-",
{
"Ref": "env"
}
]
]
},
"MessageRetentionPeriod": 1209600,
"VisibilityTimeout": 5432,
"SqsManagedSseEnabled": false
}
},
"SNSTOPIC": {
"Type": "AWS::SNS::Topic",
"Properties": {
"TopicName": {
"Fn::Join": [
"",
[
"myproject-lambda-failed-alarm-topic",
{
"Fn::Select": [
3,
{
"Fn::Split": [
"-",
{
"Ref": "AWS::StackName"
}
]
}
]
},
"-",
{
"Ref": "env"
}
]
]
}
}
},
"SNSSubscriptionEmailJoeAtGmail": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Protocol": "email",
"TopicArn": {
"Ref": "SNSTOPIC"
},
"Endpoint": "yourname+myprojectalert@gmail.com"
}
},
"SNSSubscriptionEmailJillAtQuad": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Protocol": "email",
"TopicArn": {
"Ref": "SNSTOPIC"
},
"Endpoint": "jill@stakeholder.com"
}
},
"ALARM": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmName": {
"Fn::Join": [
"",
[
"myproject-lambda-failed-dlq-alarm",
{
"Fn::Select": [
3,
{
"Fn::Split": [
"-",
{
"Ref": "AWS::StackName"
}
]
}
]
},
"-",
{
"Ref": "env"
}
]
]
},
"AlarmDescription": "There are messages in the 'Lambda Failed' dead letter queue.",
"Namespace": "AWS/SQS",
"MetricName": "ApproximateNumberOfMessagesVisible",
"Dimensions": [
{
"Name": "QueueName",
"Value": {
"Fn::GetAtt": [
"SQSDLQ",
"QueueName"
]
}
}
],
"Statistic": "Sum",
"Period": 60,
"EvaluationPeriods": 1,
"Threshold": 0,
"ComparisonOperator": "GreaterThanThreshold",
"AlarmActions": [
{
"Ref": "SNSTOPIC"
}
]
}
}
},
"Outputs": {
"SQSDLQArn": {
"Value": {
"Fn::GetAtt": [
"SQSDLQ",
"Arn"
]
}
}
},
"Description": ""
}
接下來,更新並添加新的自定義資源作為要監控的 Lambda 的依賴項。
文件: backend-config.json
"function": {
"MYLambda": {
"build": true,
"dependsOn": [
{
"attributes": [
"SQSDLQArn"
],
"category": "custom",
"resourceName": "LambdaAlarm"
}
],
"providerPlugin": "awscloudformation",
"service": "Lambda"
},
},
在您要監控的 Lambda(s) 中,對 cloudformation 進行 3 處更改:
customLambdaAlarmSQSDLQArn
) 並將其添加到Parameters
中DeadLetterConfig
屬性添加到 Lambda文件: amplify/backend/function/MyLambda/MyLambda-cloudformation-template.json
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "...",
"Parameters": {
...snip...
"customLambdaAlarmSQSDLQArn": {
"Type": "String"
},
...snip...
},
"Conditions": {...snip...},
"Resources": {
"LambdaFunction": {
"Type": "AWS::Lambda::Function",
"Metadata": {...snip},
"Properties": {
"Code": {...snip...},
"Handler": "index.handler",
"FunctionName": {...snip...},
"Environment": {
"Variables": {...snip...}
},
"Role": {...snip...},
"Runtime": "nodejs18.x",
"Architectures": ["arm64"],
"Layers": [],
"MemorySize": 256,
"Timeout": 120,
"DeadLetterConfig": {
"TargetArn": {
"Ref": "customLambdaAlarmSQSDLQArn"
}
}
}
},
"LambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": {...snip...},
"Policies": [
{
"PolicyName": "custom-lambda-execution-policy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSQSSendMessage",
"Effect": "Allow",
"Action": [
"SQS:SendMessage"
],
"Resource": {
"Ref": "customLambdaAlarmSQSDLQArn"
}
}
]
}
}
],
"AssumeRolePolicyDocument": {...snip...}
}
},
"lambdaexecutionpolicy": {...snip...},
"AmplifyResourcesPolicy": {...snip...},
"CustomLambdaExecutionPolicy": {...snip...}
},
"Outputs": {...snip...}
}
最后,由於 Amplify 怪癖,您必須amplify env checkout dev
,因為您手動觸摸了backend-config.json
文件。
然后您可以部署您的更改。 以上內容並非特定於 AWS Amplify。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.