Publishing from Lambda to an AWS IoT Topic

Publish from Lambda to AWS IoT Topic

Introduction

As the title suggests, we will see how an AWS Lambda can be used to publish to a topic on AWS IoT. In this article, we will work with Python. There are 3 steps involved:

  1. Creating the Policy
  2. Creating the Lambda
  3. Attaching the Policy to the Lambda
  4. Testing it out

Note: If you want to do the reverse, i.e., trigger a lambda based on a message received by an AWS IoT topic, check out this article.

Creating the Policy

Go to the IAM service from the services dropdown, and select ‘Policies’ from the left menu, and click on ‘Create Policy’

Create Policy

In the VisualEditor that opens up, select IoT as the service, and within Actions, select ‘Publish’ from the ‘Write’ dropdown. Select ‘All resources’ for now (you can make the resource selection ‘Specific’ later on). Don’t bother with ‘Request conditions’.

Creating the Policy 2

Click on ‘Next: Tags’ and add optional tags. Then click on ‘Next: Review’ and add a suitable name for the policy and an optional description, and click on ‘Create policy’.

Creating policy 3

Your policy is now created.

Creating the Lambda

You can either create the lambda on the console or through the serverless framework. In the console, go to ‘Lambda’ from the services dropdown. Next, click on ‘Create Function’. Choose the ‘Author from scratch’ option. Give the function a suitable name, and choose Python 3.6 as the Runtime. Leave the other settings as default, and click on ‘Create Function’.

Create lambda on console

Now within the Code Editor of the lambda, replace the existing code with the following, and then click ‘Deploy’:

import json
import boto3

client = boto3.client('iot-data', region_name='us-east-2')



def lambda_handler(event, context):
    print(event)
    # TODO implement
    # Change topic, qos and payload
    response = client.publish(
        topic='esp32/sub',
        qos=1,
        payload=json.dumps({"foo":"bar"})
    )
    print(response)
    
    return {
        'statusCode': 200,
        'body': json.dumps('Published to topic')
    }

As you must be aware, boto3 is the AWS SDK for Python. In other words, boto3 is the Python package that allows one AWS service to access others. We have a topic ‘esp32/sub’ in the us-east-2 region that was created in the How to connect ESP32 to AWS IoT Core tutorial. It is recommended that you check it out. If you have any other topics, you can replace the topic, region, QoS, and Payload. BTW, QoS refers to Quality of Service and is used in the context of the MQTT protocol. You can read more about it here.

Attaching the Policy to the Lambda

Go to the ‘Configuration’ tab of the Lambda, and click on ‘Permissions’. You will see the ‘Execution role’ block. Click on the ‘Edit’ button beside that block.

Lambda role addition 1

At the bottom, you will see a hyperlink reading ‘View the role on the IAM console’. Click on that link.

Lambda Role Addition 2

In the IAM screen that opens up, click on ‘Attach policies’, and attach the policy you just created.

Attaching the Policy

Now the lambda has this role attached.

Testing it out

Now that the Lambda is created and configured, we will test it. Open another tab on the browser, and open the MQTT Test Client of AWS IoT Core. Detailed instructions on setting up the MQTT Test Client can be found here. You want to subscribe to the esp32/sub, or whatever topic you’ve asked the lambda to publish to.

Now, go back to the lambda tab, and click on ‘Test’. If this is the first time you are testing the lambda, give the event a name and click on ‘Create’. Now click on ‘Test’ again. On the MQTT Test Client tab, you should receive the payload, every time you invoke the lambda.

Test

If you have an IoT Thing subscribed to this topic, you will be able to see that the thing too would have received the message, every time the lambda was invoked.

Congratulations! You’ve successfully posted to an AWS IoT topic using a Lambda function. I hope you liked this post.


For more tutorials on AWS, check out https://iotespresso.com/category/aws/. Also, if you are planning to become a certified AWS Solutions Architect, I’d recommend that you check out this course on Udemy. I took this course and found the lectures to be lucid, to-the-point, and fun. I hope they will help you as well.

8 comments

    1. You can treat this as publishing from any generic client to your AWS IoT. You can register a new thing from the lambda in the other account, and then publish to the required topics.

  1. i want to do the same thing but not with a lambda function on aws but with a lambda function hosted in the alexa developer console. I don’t know how to attach the policy there…i just want my alexa skill to comunicate through mqtt with a device registered on aws. All i have is an error “An error occurred (ForbiddenException) when calling the Publish operation: None”

    1. I believe from the developer console you won’t be able to publish to AWS IoT. For Smart Home skills, the recommended way is to host the lambda in your AWS account.

Leave a comment

Your email address will not be published. Required fields are marked *