Publish to IoT Endpoint of other Account - IoTData SDK NodeJS Lambda

0

Hello,
I have two Accounts running with IoT-Endpoints enabled. My devices connect to the IoT Endpoint on Account A. In Account A I also have a Lambda function running, that is receiving the messages through an IoT Rule. The Lambda determines, if the message has to be forwarded to Account B or not. Since I have other services depending on IoT messages in Account B as well, I just want to republish the MQTT message to the IoT-Endpoint of Account B.

Lambda is configured with NodeJS 12.x.

Let's leave the IAM stuff aside. I have some roles/policies set up for that already, but I do not even get that far to test them.

I use the following snippet in Lambda of Account A to send the message to the IoT-Endpoint of Account B.

  let iotData = new AWS.IotData({
    endpoint: &#39;<endpointOfAccountB>-ats.iot.eu-west-1.amazonaws.com&#39;
  });
  
  let topic_params = {
    topic: "my/topic/on/other/account",
    payload: JSON.stringify(payload),
    qos: 1
  };
  
 iotData.publish(topic_params).promise();

It seems like the endpoint attribute is just ignored, because the message gets published on Account A instead. I also tried without -ats (result of CLI: aws iot describe-endpoint ):
<endpointOfAccountB>.iot.eu-west-1.amazonaws.com -> same result

When I print iotDev.endpoint the correct endpoint is configured.

Is there a way to publish an MQTT message from Account A to Account B with the IoTData sdk?
Am I missing something?
Feel free to ask for more details if necessary.

Best Regards,
Julian

asked 4 years ago1364 views
2 Answers
1
Accepted Answer

Encountered this same problem today as well. What I did to over come this was assume a Role in Account B, set the credentials in the AWS.config.credentials with the temp creds, then create the IotData object with the IoT endpoint before you publish the message.

   let credentials = await STS.assumeRole({
      RoleArn: 'arn:aws:iam::123456789:role/iotRole',
      RoleSessionName: 'testRoleSessionName'
    }).promise();

   const remoteCredentials = new AWS.Credentials(
      credentials.Credentials.AccessKeyId, 
      credentials.Credentials.SecretAccessKey, 
      credentials.Credentials.SessionToken);  

    const iotData = new AWS.IotData({
      endpoint: 'a3m99gntexample-ats.iot.us-east-1.amazonaws.com', // IoTEndpoint of Account B
      credentials: remoteCredentials
    });

    const data = await iotData.publish({
      topic: `topicfilter/data/clientIdHere`,
      payload: JSON.stringify({event: 'whatever'}),
      qos: 1
    }).promise();

Be sure to give the lambda's execution role in Account A the permission to STS:AssumeRole and setup the "iotRole" in Account B to trust Account A.

Edited by: jofamaws on May 5, 2020 12:39 PM

answered 4 years ago
0

Thank you very much!

Worked as described.

answered 4 years ago

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.

Guidelines for Answering Questions