I have a lambda. This lambda creates a thing by doing something like:
const cfnThing = new iot.CfnThing(this, 'MyCfnThing', /* all optional props */ {
attributePayload: {
attributes: {
attributesKey: 'attributes',
},
},
thingName: 'thingName',
});
But I want to create a thing on a different account. I created a role so it can be assumed. But I don't understand how to change credentials for the thing creation operation. I found that for s3 operations it can be done by putting new credentials to the client. Is there a client for iot too? Is there any other way to do that?
You first need to create a role in the destination account. Then in your lambda, in source account, you need to assume the role. Here is a piece of code I'm using to assume the role with automatic refresh of the credentials:
This is the credentials.py:
import boto3
from botocore.credentials import RefreshableCredentials
from boto3 import Session
from botocore.session import get_session
def refreshed_session(role_arn, region='eu-central-1'):
"""Assume a boto3.Session With automatic credential renewal.
Args:
region (str, optional): The region of the session.
Defaults to 'eu-central-1'.
Returns:
session (Session): an boto3 session with RefreshableCredentials
"""
def _refresh():
" Refresh tokens by calling assume_role again "
params = {
"RoleArn": role_arn,
"RoleSessionName": "cross_acct_lambda",
"DurationSeconds": 3600,
}
sts_client = boto3.client("sts", region_name='eu-central-1')
response = sts_client.assume_role(**params).get("Credentials")
credentials = {
"access_key": response.get("AccessKeyId"),
"secret_key": response.get("SecretAccessKey"),
"token": response.get("SessionToken"),
"expiry_time": response.get("Expiration").isoformat(),
}
return credentials
session_credentials = RefreshableCredentials.create_from_metadata(
metadata=_refresh(),
refresh_using=_refresh,
method="sts-assume-role",
)
session = get_session()
session._credentials = session_credentials
session.set_config_variable("region", region)
return Session(botocore_session=session)
And then in lambda you can use it like this:
# create service client using the assumed role credentials, e.g. iot-data
boto3_session = credentials.refreshed_session(account_destination_role_arn)
iot_client = boto3_session.client('iot-data')
Any call to AWS IoT Control Plane API using iot_client
will be on the destination account.