Skip to content

SES ReceiptRule Actions not happening

0

Hi. I have the following cloudformation template. If I send an email to my recipient, I can receive it using a mail client, but it never reaches the Lambda or S3 Action.

  • My Lambda log group does not exist, so I know the lambda has never been executed.
  • In the S3 bucket I have the common AMAZON_SES_SETUP_NOTIFICATION file.
  • My SES is not in sandbox and have recieve limits to 14 per second.
  • My domain is verified (DMIK, DMARC, MX record all in place)
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  _

  Sample SAM Template for _
  
Parameters:
  RawBucketName:
    Type: String
    Description: The S3 bucket where the raw images and videos is stored.
    Default: mybucket
  DomainName:
    Type: String
    Description: Domain name for the email address
    Default: domain.co.za
  CreateBucket:
    Type: String
    Default: "false"
    AllowedValues: ["true", "false"]

Conditions:
  ShouldCreateBucket: !Equals [!Ref CreateBucket, "true"]

Resources:
  MyRawBucket:
    Type: AWS::S3::Bucket
    Condition: ShouldCreateBucket
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      BucketName: !Ref RawBucketName
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      NotificationConfiguration:
        QueueConfigurations:
          - Event: s3:ObjectCreated:*
            Queue: !Sub "arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:${TransmitRawFilesQueueName}"
    DependsOn: SQSQueuePolicy

  TransmitRawFilesQueue:
    Type: "AWS::SQS::Queue"
    Properties:
      QueueName: !Ref TransmitRawFilesQueueName
      SqsManagedSseEnabled: true
      MessageRetentionPeriod: 1209600 # 14 days
      RedrivePolicy:
        deadLetterTargetArn: !GetAtt TransmitRawFilesDLQ.Arn
        maxReceiveCount: 5

  TransmitRawFilesDLQ:
    Type: "AWS::SQS::Queue"
    Properties:
      QueueName: !Sub "${TransmitRawFilesQueueName}-DLQ"
      SqsManagedSseEnabled: true
      MessageRetentionPeriod: 1209600 # 14 days

  SQSQueuePolicy:
    Type: AWS::SQS::QueuePolicy
    Properties:
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: s3.amazonaws.com
            Action: SQS:SendMessage
            Resource: !GetAtt TransmitRawFilesQueue.Arn
            Condition:
              ArnLike:
                aws:SourceArn: !Sub "arn:aws:s3:::${RawBucketName}"
      Queues:
        - Ref: TransmitRawFilesQueue

  FilesQueueLambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: SQSPolling
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - sqs:ReceiveMessage
                  - sqs:DeleteMessage
                  - sqs:GetQueueAttributes
                Resource: !GetAtt TransmitRawFilesQueue.Arn
        - PolicyName: DetectLabels
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - rekognition:DetectLabels
                Resource: "*"
        - PolicyName: S3ReadPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                  - s3:ListBucket
                Resource: !Sub "arn:aws:s3:::${RawBucketName}/*"

  HandleRawFilesFunction:
    Type: AWS::Serverless::Function
    Properties:
      Runtime: nodejs20.x
      Timeout: 30
      MemorySize: 1024
      CodeUri: handle_raw_files/
      Handler: app.handler
      Events:
        SQSEvent:
          Type: SQS
          Properties:
            Queue: !GetAtt TransmitRawFilesQueue.Arn
            BatchSize: 1
      Role: !GetAtt FilesQueueLambdaExecutionRole.Arn

  HandleIncomingMailRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

  HandleIncomingMailFunction:
    Type: AWS::Serverless::Function
    Properties:
      Runtime: nodejs20.x
      Timeout: 30
      MemorySize: 1024
      CodeUri: handle_incoming_mail/
      Handler: app.handler
      Role: !GetAtt HandleIncomingMailRole.Arn

  HandleIncomingMailPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref HandleIncomingMailFunction
      Action: lambda:InvokeFunction
      Principal: ses.amazonaws.com
      SourceAccount: !Ref AWS::AccountId
      SourceArn: !Sub "arn:aws:ses:${AWS::Region}:${AWS::AccountId}:receipt-rule-set/*:receipt-rule/*"

  HandleIncomingMailToS3Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ses.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: s3access
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:PutObject
                Resource: !Sub "arn:aws:s3:::${RawBucketName}/*"

  EmailReceiptRuleSet:
    Type: AWS::SES::ReceiptRuleSet
    Properties:
      RuleSetName: "StoreEmailsRuleSet"

  EmailReceiptRule:
    Type: AWS::SES::ReceiptRule
    DependsOn: HandleIncomingMailPermission
    Properties:
      RuleSetName: !Ref EmailReceiptRuleSet
      Rule:
        Name: "EmailToLambdaRule"
        Enabled: true
        ScanEnabled: true
        Recipients:
          - !Sub "upload@${DomainName}"
        Actions:
          - S3Action:
              BucketName: !Ref RawBucketName
              IamRoleArn: !GetAtt HandleIncomingMailToS3Role.Arn
          - LambdaAction:
              FunctionArn: !GetAtt HandleIncomingMailFunction.Arn
              InvocationType: "Event"
        TlsPolicy: "Require"

  EmailBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref RawBucketName
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: ses.amazonaws.com
            Action: s3:PutObject
            Resource: !Sub "arn:aws:s3:::${RawBucketName}/*"
            Condition:
              StringEquals:
                aws:SourceAccount: !Ref AWS::AccountId
1 Answer
1

Based on the provided CloudFormation template and the described issue, there are a few potential reasons why the SES ReceiptRule Actions (Lambda and S3) are not being triggered when you send an email:

  1. Rule Set Activation: The template creates a ReceiptRuleSet, but it doesn't explicitly activate it. SES requires an active rule set to process incoming emails. You may need to manually activate the rule set in the SES console or add a step in your deployment process to activate it.

  2. Email Address Configuration: Ensure that the email address "upload@domain.co.za" (replace domain.co.za with your actual domain) is properly configured and verified in SES. The rule is set to trigger only for this specific recipient.

  3. TLS Policy: The rule has a TlsPolicy set to "Require". Make sure that the sending mail server supports TLS, or consider changing this to "Optional" for testing purposes.

  4. S3 Bucket Permissions: While the template includes an S3 bucket policy allowing SES to put objects, ensure that the bucket actually exists if you're not creating it in this template (CreateBucket parameter is set to "false" by default).

  5. Lambda Function Code: The template defines the Lambda function, but make sure that the actual code in the "handle_incoming_mail" directory is correctly implemented to process the SES event.

  6. CloudWatch Logs: Check the CloudWatch Logs for the SES service to see if there are any error messages or indications of why the actions are not being triggered.

To troubleshoot:

  1. Verify that the ReceiptRuleSet is active in the SES console.
  2. Double-check the email address configuration and verification status in SES.
  3. Temporarily set the TlsPolicy to "Optional" for testing.
  4. Ensure the S3 bucket exists and has the correct permissions.
  5. Review the Lambda function code for any potential issues.
  6. Check CloudWatch Logs for both SES and the Lambda function for any error messages.

If these steps don't resolve the issue, you may need to contact AWS Support for further assistance, as there might be an account-specific configuration or limitation affecting the SES ReceiptRule processing.
Sources
Granting permissions to publish event notification messages to a destination - Amazon Simple Storage Service
Giving permissions to Amazon SES for email receiving - Amazon Simple Email Service

answered 2 years ago

EXPERT

reviewed 2 years ago

  • I activated the rule in the console; my domain is replaced with my verified domain; I tried without TLSPolicy also; Bucket exists; Lambda exists in directory and is created successfully; Can't find any logs in CloudWatch

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.