3
votes

I am trying to publish message from AWS Lamba using Nodejs to AWS IoT . I have zipped the project and uploaded on to the AWS IoT below is the code snippet

 var awsIot = require('aws-iot-device-sdk');

 var device = awsIot.device({
  keyPath: 'keyfilepath',
  certPath: 'pem file path',
  caPath: 'root-CA.crt',
  clientId: 'iotTest7526532135',
  host: 'host id'
 });


device
  .on('connect', function() {
     console.log('connect');
     device.subscribe('topic_3');

     device.publish('topic_1', JSON.stringify({ message_id:23,Message:'HelloWorld'}));
    });

     device
     .on('message', function(topic, payload) {
console.log('message', topic, payload.toString());
 });

I am getting below error
"errorMessage": "Cannot find module 'aws-iot-device-sdk'",

I know that iot sdk is missing, I am not sure how to install it on AWS Lambda.

Any suggestions will be really helpful

5

5 Answers

16
votes

I would highly recommend not using the aws-iot-device-sdk to interact with AWS Iot from a Lambda function.

You need to understand there are 2 javascript APIs that you can use to access AWS IoT

  • The AWS IOT Device SDKs for javascript, using MQTT as a protocol and x509 certificates for authentication. These are typically used in devices running outside of your AWS cloud.
  • The AWS SDK for javascript, using HTTP as a protocol, and IAM roles (among other things) for authentication. These SDKs are typically run inside your AWS cloud (such as a Lambda)

There are multiple reasons why you should opt for the HTTP based SDK :

  • The aws-iot-device-sdk is specifically targeted toward devices "living" outside of Aws (IoT gateways / devices in the field) that need to remotely connect.
  • The Device SDK uses MQTT and x509 certificates to interact with AWS IoT. There is no need to configure x509 securities in your lambda. A Lambda running on your AWS account can easily access AWS IoT through an IAM role, so if your lambda function is configured with the correct role, you can use the standard aws sdks.
  • A protocol like MQTT (or any pub/sub protocol) doesn't match well with a serverless lambda architecture. In your lambda function you are subscribing to a topic, something that you don't typically do in a short-lived lambda function.
  • The AWS SDK for NodeJS is provided to your lambda out of the box.There's no need to require or package additional node modules)

Your code can become as simple as this (notice that there are no credentials or extra node modules required) :

var AWS = require('aws-sdk');

var iotdata = new AWS.IotData({endpoint:"yourendpoint.iot.eu-central-1.amazonaws.com"});

exports.handler = function(event, context, callback) {

console.log("found iotdata",iotdata);

    var params = {
        topic: 'topic/test',
        payload: 'blah',
        qos: 0
        };


    iotdata.publish(params, function(err, data){
        if(err){
            console.log("Error occured : ",err);
        }
        else{
            console.log("success.....");
        }
    });

    callback();
};
2
votes

When you zip your project, you also zip ./node_modules folder. So as long as aws-iot-device-sdk is there (along with all the dependencies), your Lambda will be fine.

So all you need is:

npm install aws-iot-device-sdk
zip ...
2
votes

You'll need to make sure you're uploading your package.json file as well, which should have a dependency requirement for aws-iot-device-sdk

you can add the package to your package.json by running

npm -i --save aws-iot-device-sdk

from your project directory.

0
votes

Add something like the below in your package.json file. then run npm install. This will create a node_modules folder. Now zip it and upload it once again.

"aws-iot-device-sdk": "^2.1.0"
0
votes

If you are just going to publish the data to IoT topic, you are better of using http protocol instead of MQTT connection.

And using HTTP connection doesnt require aws-iot-device-sdk package. AWS default SDK has iotdata. And iotdata will provide the http connection to the device.

iotHTTPConnection= AWS.IotData({endpoint: Your_END_POINT});

iotHTTPConnection.publish(params) will publish the data using http without iot specific sdk.

https://docs.aws.amazon.com/iot/latest/apireference/API_iotdata_Publish.html

There is no http subscribe though.