簡體   English   中英

需要幫助為 SNS 觸發的 Lambda 配置 DLQ

[英]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 通知。

Lambda 錯誤電子郵件通知

要實施此解決方案,您必須創建以下內容:

  • SNS話題
  • IAM 角色
  • 一個 Lambda function
  • CloudWatch 日志觸發器

正如@fedonev 所指出的,當無法傳遞事件時,將使用 SNS 訂閱的(對於 lambda)DLQ。 如果事件已傳送(但 Lambda 失敗),您可以使用 Lambda 的異步事件 DLQ 或連接 Lambda 的“失敗時”目標。

我正在使用 AWS Amplify 並決定使用 Lambda 的“異步”DLQ 而不是 lambda 目標。

第 1 步 - 添加自定義類別以添加:

  • SQS (dlq) 保存失敗的嘗試事件
  • 監視 SQS 資源的 CloudWatch 警報
  • 警報使用的 SNS 主題和訂閱

並“輸出”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 處更改:

  1. 從您的自定義類別中拉入 output 變量 ( customLambdaAlarmSQSDLQArn ) 並將其添加到Parameters
  2. DeadLetterConfig屬性添加到 Lambda
  3. 向 LambdaExecutionRole 添加策略

文件: 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM