CloudFormation Eventbridge and SQS Rule

Hello,

i have the following problem:
I added in my serverless.yml file custom cloud formation resources, with the following config lines:

custom:
  eventBusName: test-bus-${opt:stage, self:provider.stage}

functions:
  sqs-consume:
    handler: Lambda/build/SQSConsume.handler
    events:
      - sqs:
         arn: !GetAtt lamDIONSQS.Arn
         batchSize: 1

resources:
  Resources:
    EventBridge:
      Type: AWS::Events::EventBus
      Properties:
        Name: ${self:custom.eventBusName}

     EventBridgeSQSRule:
       Type: AWS::Events::Rule
       Properties:
          Description: "Test Event Bus"
          EventBusName: ${self:custom.eventBusName}
          EventPattern: { "source": [ "test.v1" ]}
          State: ENABLED
          Targets:
            -
             Arn: !GetAtt SQS
             Id: "SQSQueueTestV1"

      SQS:
        Type: AWS::SQS::Queue

The EventBridge SQS rule is created but no messages are sent to the SQS queue. The rule only works when I log into the AWS console and manually click on “Edit” -> “Update”. When I do these steps, the rule works and my SQA queue is triggered.

It would be very nice if someone can help me with this issue!

Thank you very much!

Hello!

It works if you “refresh” it manually via AWS web console, because in addition to creating the rule, AWS also creates needed privileges for putting messages into SQS by EventBridge rule.

For Lambda functions, you have to let the EventBridge Rule invoke the function itself. It can be done this way:

resources:
  Resources:

    EventBridge:
      Type: AWS::Events::EventBus
      Properties:
        Name: "custom-eventbus"

    EventBridgeLambdaRule:
      Type: AWS::Events::Rule
      Properties:
        Description: "Test Event Bus"
        EventBusName: "custom-eventbus"
        EventPattern: { "source": [ "my.custom.event" ]}
        State: ENABLED
        Targets:
          - Arn: !GetAtt SubscriberLambdaFunction.Arn
            Id: "LambdaTest"

    LambdaInvokePermission:
      Type: AWS::Lambda::Permission
      Properties:
        Action: lambda:InvokeFunction
        FunctionName: !GetAtt SubscriberLambdaFunction.Arn
        Principal: 'events.amazonaws.com'
        SourceArn: !GetAtt EventBridgeLambdaRule.Arn

And for sure if you are using SQS, you need to do the same for SQS. I’m not really sure how you can achieve that, but my bet is, that AWS::SQS::QueuePolicy is way to go:

SampleSQSPolicy: 
  Type: AWS::SQS::QueuePolicy
  Properties: 
    Queues: 
      - !Ref YourSQSResource
    PolicyDocument: 
      Statement: 
        - Action: 
            - "SQS:SendMessage" 
            - "SQS:ReceiveMessage"
            - "SQS:GetQueueAttributes"
          Effect: "Allow"
          Resource: !GetAtt EventBridgeSQSRule.Arn
          Principal:
            AWS: 
              - 'events.amazonaws.com'

I was basing it on examples from AWS documentation:


Let us know what is the correct configuration for SQS, it might be useful in the future, because with SQS we can do the batch processing with EventBridge -> SQS -> Lambda architecture.

okay thank you very much for helping me. You have brought me quite a bit further!!
I had to change a little bit on your SQS Policy but the direction was fully right.
Because sharing is caring, I want to provide the solution for everyone.

The final working example:

SQSPolicy:
  Type: AWS::SQS::QueuePolicy
  Properties:
    Queues:
      - !Ref SQSQueue
    PolicyDocument:
      Statement:
        - Action:
            - "SQS:SendMessage"
          Effect: "Allow"
          Resource: !GetAtt SQSQueue.Arn
          Principal:
            Service:
              - "events.amazonaws.com"
          Condition:
            ArnEquals:
              aws:SourceArn: !GetAtt EventBridgeSQSRule.Arn
1 Like