将 MQTT 消息从不同账户的 Lambda 发布到 AWS IoT Core

Publish MQTT message to AWS IoT Core from Lambda on a different account

我正在尝试使用其他账户从 Lambda 向 AWS IoT Core 发布 MQTT 消息。

假设A账户是IoT核心账户,B账户是lambda函数账户

在帐户 A 上: 我使用 B 的账户 ID 和 AWSIoTDataAccess 策略创建了以下角色类型 'Another AWS account':

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect",
                "iot:Publish",
                "iot:Subscribe",
                "iot:Receive",
                "iot:GetThingShadow",
                "iot:UpdateThingShadow",
                "iot:DeleteThingShadow"
            ],
            "Resource": "*"
        }
    ]
}

在帐户 B 上: 我有一个 lambda 函数 nodejs

 // Get the Cross account credentials
const accessparams = new Promise((resolve, reject) => {
        const timestamp = (new Date()).getTime();
        const params = {
            RoleArn: 'arn:aws:iam::' + id + ':role/' + remoteRole,
            RoleSessionName: `be-descriptibe-here-${timestamp}`
        };
        sts.assumeRole(params, (err, data) => {
            if (err) reject(err);
            else {
                resolve({
                    accessKeyId: data.Credentials.AccessKeyId,
                    secretAccessKey: data.Credentials.SecretAccessKey,
                    sessionToken: data.Credentials.SessionToken,
                });
            }
        });
    });

iot.remote = new AWS.IotData({ accessparams, endpoint: accountInfo.endpoint, region: 'ca-central-1', });

    var params = {
        topic: "MyTopic",
        payload: 'payload',
        qos: 0
    };

 try {
        var result = await iot.remote.publish(params).promise();
        console.log('result', result);
        return buildResponse({ "result": "ok" });
    } catch (err) {
        console.log("ERROR => " + JSON.stringify(err));
        return buildErrorResponse("Error");
    }

我无法发布任何数据,出现以下错误,看起来它从未承担帐户 A 的角色。

{
    "message": "The client used a Server Name Indication (SNI) that is not associated with this account.",
    "code": "ForbiddenException",
    "time": "2021-05-29T16:21:11.254Z",
    "requestId": "c2f78026-cc64-091b-8b66-0322c26a26bb",
    "statusCode": 403,
    "retryable": false,
    "retryDelay": 84.76771000356665
}

如有任何意见或建议,我们将不胜感激。

提前致谢,

丹尼尔

要获取跨账号数据交互,我们需要按照以下步骤进行:

  1. 在您想要 push/pull 数据的帐户 from/to 中创建一个角色(在您的示例帐户 A 中,即使用 IOT Core)

  2. 为该角色创建信任

  3. 在账户 B(您使用的是 lambda)中使用“sts:AssumeRole”来为账户 A 中的 access/privilege 分配角色。

在您的代码中我没有看到“sts:AssumeRole”,可能这就是导致问题的原因。可以参考How can I configure a Lambda function to assume a role from another AWS account?

我在我的代码中发现了错误,当我将参数传递给 IOTData 时,我必须将 endpointregion 添加到 accessparameter 而不是放在同一行。

 accessparams.endpoint =iotEndpoint;
 accessparams.region = 'ca-central-1' ;

 iot.remote = new AWS.IotData( accessparams);

感谢所有花时间检查它并尝试找到解决方案的人。