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 Respuesta
0
Respuesta aceptada

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
EXPERTO
Greg_B
respondido hace 2 años

No has iniciado sesión. Iniciar sesión para publicar una respuesta.

Una buena respuesta responde claramente a la pregunta, proporciona comentarios constructivos y fomenta el crecimiento profesional en la persona que hace la pregunta.

Pautas para responder preguntas