You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SES规则转存S3后未触发SNS至SQS通知问题排查

问题:SES接收规则转存S3正常,但SQS队列始终为空,遗漏哪些配置?

我配置了SES接收规则,将邮件转存至S3存储桶,同时设置SNS主题订阅SQS队列,对应的Terraform配置如下:

resource "aws_ses_receipt_rule_set" "chat-replies" {
  rule_set_name = "${local.deployment-name}-chat-replies"
}

resource "aws_ses_active_receipt_rule_set" "chat-replies" {
  rule_set_name = aws_ses_receipt_rule_set.chat-replies.id
}

resource "aws_ses_receipt_rule" "chat-replies" {
  name          = "${local.deployment-name}-chat-replies-store"
  rule_set_name = aws_ses_receipt_rule_set.chat-replies.id
  recipients    = [local.emails-chat-replies-domain]
  enabled       = true
  scan_enabled  = true

  s3_action {
    bucket_name = aws_s3_bucket.chat-replies.bucket
    position    = 1
    topic_arn   = aws_sns_topic.chat-replies.arn
  }

  depends_on = [aws_s3_bucket_policy.chat-replies]
}

resource "aws_s3_bucket" "chat-replies" {
  bucket   = "${local.deployment-name}-chat-replies"
}

resource "aws_s3_bucket_acl" "chat-replies" {
  bucket   = aws_s3_bucket.chat-replies.id
  acl      = "private"
}

resource "aws_s3_bucket_public_access_block" "chat-replies" {
  bucket                  = aws_s3_bucket.chat-replies.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_s3_bucket_policy" "chat-replies" {
  bucket   = aws_s3_bucket.chat-replies.id

  policy = <<POLICY
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowSESPuts",
            "Effect": "Allow",
            "Principal": {
                "Service": "ses.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "${aws_s3_bucket.chat-replies.arn}/*",
            "Condition": {
                "StringEquals": {
                    "aws:Referer": "${data.aws_caller_identity.current.account_id}"
                }
            }
        }
    ]
}
POLICY
}

resource "aws_sns_topic" "chat-replies" {
  name     = "${local.deployment-name}-chat-replies"
}

resource "aws_sqs_queue" "chat-replies" {
  name                      = "${local.deployment-name}-chat-replies"
  message_retention_seconds = 604800 # 7 days
  receive_wait_time_seconds = 20     # long poll
}

resource "aws_sns_topic_subscription" "chat-replies" {
  topic_arn = aws_sns_topic.chat-replies.arn
  protocol  = "sqs"
  endpoint  = aws_sqs_queue.chat-replies.arn
}

resource "aws_sns_topic_policy" "chat-replies" {
  arn      = aws_sns_topic.chat-replies.arn
  policy   = data.aws_iam_policy_document.sns-chat-replies.json
}

data "aws_iam_policy_document" "sns-chat-replies" {
  statement {
    actions = [
      "SNS:Publish",
    ]

    condition {
      test     = "StringEquals"
      variable = "AWS:SourceAccount"

      values = [
        data.aws_caller_identity.current.account_id,
      ]
    }

    effect = "Allow"
    principals {
      type = "Service"
      identifiers = [
        "ses.amazonaws.com"
      ]
    }

    resources = [aws_sns_topic.chat-replies.arn]
  }
}

output "chat-replies-queue-url" {
  value = aws_sqs_queue.chat-replies.url
}

目前S3存储桶中可正常接收邮件,但SQS队列始终为空,请问我遗漏了哪些配置?


遗漏的关键配置点

1. SES规则的通知逻辑错误:S3 Action的Topic ARN仅在存储失败时触发

你当前在s3_action里指定的topic_arn,只有当SES将邮件存储到S3失败时,才会向SNS主题发送通知。如果想实现「每收到一封邮件就触发SNS通知」,需要在SES接收规则中单独添加一个sns_action块,而不是依赖S3 Action的错误通知:

resource "aws_ses_receipt_rule" "chat-replies" {
  # 保留现有其他配置...

  s3_action {
    bucket_name = aws_s3_bucket.chat-replies.bucket
    position    = 1
    # 可移除这里的topic_arn(仅用于失败通知)
  }

  # 添加单独的SNS通知动作,邮件成功接收时触发
  sns_action {
    topic_arn = aws_sns_topic.chat-replies.arn
    position  = 2
    encoding  = "UTF-8"
  }
}

2. SQS队列缺少允许SNS主题发送消息的权限策略

SNS主题需要被授权向SQS队列发送消息,你当前只配置了SNS允许SES发布的策略,但SQS本身没有开放权限。需要添加SQS队列策略:

resource "aws_sqs_queue_policy" "chat-replies" {
  queue_url = aws_sqs_queue.chat-replies.url
  policy    = data.aws_iam_policy_document.sqs-chat-replies.json
}

data "aws_iam_policy_document" "sqs-chat-replies" {
  statement {
    actions   = ["sqs:SendMessage"]
    effect    = "Allow"
    principals {
      type        = "AWS"
      identifiers = [aws_sns_topic.chat-replies.owner]
    }
    resources = [aws_sqs_queue.chat-replies.arn]

    condition {
      test     = "ArnEquals"
      variable = "aws:SourceArn"
      values   = [aws_sns_topic.chat-replies.arn]
    }
  }
}

3. 确认SNS订阅状态

SQS订阅SNS主题后,AWS会自动发送一条订阅确认消息到队列。如果没有消费并确认这条消息,订阅会处于「未确认」状态,SNS不会投递后续消息。可以通过AWS控制台检查SNS订阅的状态,或者确保你的消费逻辑能处理订阅确认消息。


内容的提问来源于stack exchange,提问作者GlinesMome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 03:25:01