ForbiddenException error when using the boto3 publish method with IoTDataPlane

0

I'm attempting to publish to an IoT topic within a lambda using the publish method for the boto3 IoTDataPlane client. However when I invoke the lambda, I get the following exception:

[ERROR] ClientError: An error occurred (ForbiddenException) when calling the Publish operation: None

I have also added an AWS IoT policy to the lambda.

Here's a snippet of the lambda:

import boto3
import json
import logging

logger = logging.getLogger(__name__)
logger.setLevel("DEBUG")

iot_client = boto3.client('iot', region_name='us-east-1')
endpoint_response = iot_client.describe_endpoint(endpointType='iot:Data-ATS')
endpoint_url = f"https://{endpoint_response['endpointAddress']}"
logger.debug(endpoint_url)
client = boto3.client('iot-data', region_name='us-east-1', endpoint_url=endpoint_url)

def handler(event, context):
    topic = "test/topic"
    datum = json.dumps({"a": "b"})
    logger.debug(datum)

    response = client.publish(
        topic=topic,
        qos=0,
        payload=datum,
        retain=True
    )

    logger.debug(response)

And this is the policy statement associated with the lambda:

self._handler.add_to_role_policy(
    iam.PolicyStatement(
        actions=[
            "iot-data:Publish",
            "iot-data:Close",
            "iot-data:AttachPolicy",
            "iot-data:ListNamedShadowsForThing",
            "iot:DescribeEndpoint"
        ],
        resources=[
            "*"
        ],
    )
)
1 réponse
0
Réponse acceptée

Hi. I can see why you might assume there is, but there's no iot-data service. You can replace all iot-data references in the policy with just iot. Then you'll be able to publish. BTW, there's no iot:Close action.

Additionally (if the Lambda is in the same account and region as the IoT Core endpoint you want to use), you don't have to explicitly set the endpoint or the region so you could reduce the code down to something like:

import boto3
import json
import logging

logger = logging.getLogger(__name__)
logger.setLevel("DEBUG")

client = boto3.client('iot-data')

def handler(event, context):
    topic = "test/topic"
    datum = json.dumps({"a": "b"})
    logger.debug(datum)

    response = client.publish(
        topic=topic,
        qos=0,
        payload=datum,
        retain=True
    )

    logger.debug(response)

Then you could delete the DescribeEndpoint action from the policy too. And presently, you aren't using the ListNamedShadowsForThing or AttachPolicy actions so these could be deleted too (but you probably know that).

profile pictureAWS
EXPERT
Greg_B
répondu il y a 2 ans

Vous n'êtes pas connecté. Se connecter pour publier une réponse.

Une bonne réponse répond clairement à la question, contient des commentaires constructifs et encourage le développement professionnel de la personne qui pose la question.

Instructions pour répondre aux questions