Select your cookie preferences

We use cookies and similar tools to enhance your experience, provide our services, deliver relevant advertising, and make improvements. Approved third parties also use these tools to help us deliver advertising and provide certain site features.

IoT rule to SQS queue

Created with SnapIoTSQS

Send to an SQS queue from an IoT rule

This SAM template deploys resources needed to send iot events to IoT Core service to forward these events through an IoT Rule to SQS Queue with bring-your-own custom authozier for device authentication.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Serverless Pattern - IoT rule with custom lambda authorizer forwarding events to SQS for post iot event processing (uksb-1tthgi812) (tag:iot-mqttoverhttp-customauth)
Parameters:
  VPC:
    Type: AWS::EC2::VPC::Id
  Subnets:
    Type: List
Resources:
  IotEventQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: iot-events 
  ProcessorSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: iot-events-processor
      VpcId: !Ref VPC
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
  Processor:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: iot-events-processor
      Handler: app.handler
      Runtime: nodejs20.x
      Timeout: 29
      CodeUri: src/
      Events:
        IotEvent:
          Type: SQS
          Properties:
            Queue: !GetAtt IotEventQueue.Arn
            BatchSize: 10000
            MaximumBatchingWindowInSeconds: 5
      VpcConfig:
        SecurityGroupIds:
          - !Ref ProcessorSecurityGroup
        SubnetIds: !Ref Subnets
  TopicRuleRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: iot-topic-forwarder
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - iot.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: /
      Policies:
      - PolicyName: iot-topic-forwarder-policy
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
              - sqs:SendMessage
            Resource: !GetAtt IotEventQueue.Arn 
  SQSRule:
    Type: AWS::IoT::TopicRule
    Properties:
      RuleName: device_events
      TopicRulePayload:
        Sql: SELECT * 
        Actions:
          - Sqs: 
              QueueUrl: !Ref IotEventQueue
              RoleArn: !GetAtt TopicRuleRole.Arn



  LambdaAuthorizer:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: iot-publish-authorizer
      Handler: index.handler
      Runtime: nodejs20.x
      Environment:
        Variables:
          AWS_ACCOUNTID: !Ref AWS::AccountId
      InlineCode: |
        exports.handler = function(event, context, callback) { 
          var deviceId = event.protocolData.http.headers["x-device-id"];
          callback(null, generateAuthResponse(deviceId)); 
        };

        var generateAuthResponse = function(deviceId) {
          var response = {};
          response.isAuthenticated = true;
          response.principalId = deviceId;
          var policy = {};
          policy.Version = '2012-10-17';
          policy.Statement = [];
          var publishStatement = {}; 
          var connectStatement = {};
          connectStatement.Action = ["iot:Connect"];
          connectStatement.Effect = 'Allow';
          connectStatement.Resource = ["*"];
          publishStatement.Action = ["iot:Publish"]; 
          publishStatement.Effect = 'Allow'; 
          publishStatement.Resource = [`arn:aws:iot:${process.env.AWS_REGION}:${process.env.AWS_ACCOUNTID}:topic/*`]; 
          policy.Statement[0] = connectStatement;
          policy.Statement[1] = publishStatement; 
          response.policyDocuments = [policy];
          response.disconnectAfterInSeconds = 3600;
          response.refreshAfterInSeconds = 300;
          
          return response;
        };

  CustomAuthorizer:
    Type: AWS::IoT::Authorizer
    Properties:
      AuthorizerName: anonymous-authorizer
      Status: ACTIVE
      SigningDisabled: true
      AuthorizerFunctionArn: !GetAtt LambdaAuthorizer.Arn
  IotLambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !GetAtt LambdaAuthorizer.Arn
      Principal: iot.amazonaws.com
      Action: lambda:InvokeFunction

          
      

< Back to all patterns


GitHub icon Visit the GitHub repo for this pattern.

Download

git clone https://github.com/aws-samples/serverless-patterns/ cd serverless-patterns/iot-mqttoverhttp-customauth

Deploy

sam deploy --guided


Testing

Use your choise of http client for testing against this endpoint: POST ${IoT Core Data Endpoint}/topics/$aws/rules/device_events with json body and http header 'x-amz-customauthorizer-name: anonymous-authorizer'.

Cleanup

1. Delete the stack: sam delete --stack-name STACK_NAME.
2. Confirm the stack has been deleted: aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'STACK_NAME')].StackStatus"

Enoch Tsai

Presented by Enoch Tsai

Enoch Tsai is a cloud application architect advocate for Serverless Applications at Amazon Web Services based in the US. Prior to joining AWS Enoch worked in a number of different technical roles specializing in native cloud development and adaption for enterprise system.