How to do cross account Sagemaker endpoint requests in AWS
In this blog post I want to show you how to do cross-account Sagemaker endpoint requests in AWS.
We have two accounts, a parent account and a child account. The parent account hosts the Sagemaker endpoint and we want to call it from the child account.
Based on this blog post
High level solution
- In parent account
- Create a policy
SageMakerExternalInvokeEndpoint
that allows you to execute the Sagemaker endpoint - Create a role
SagemakerExternal
and add child account as trusted account
- Create a policy
- In child account
- Create a lambda on the child account to invoke the API with
- Change the execution role of the lambda to allow
sts:AssumeRole
onSagemakerExternal
(which is possible because we added it as a trusted account)
In the parent account
In the parent account we are going to do 2 things:
- Create a policy
SageMakerExternalInvokeEndpoint
that will give us permission to call the endpoints on this account - Create a role
SagemakerExternal
having this policy that can be assumed by someone else (the child account)
Log in to the parent account.
Here we configured the endpoint(s) we want to hit cross-account.
Copy the ARN of the endpoint we want to hit.
Make a new policy that allows someone to invoke Sagemaker endpoints in this account.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["sagemaker:InvokeEndpoint"],
"Effect": "Allow",
"Resource": "arn:aws:sagemaker:eu-west-1:<parent account id>:endpoint/*"
}
]
}
Log in to IAM.
Go to policies.
Click on create policy.
Paste the json above.
If you want to, make the policy more generic with wildcards *
.
Name it SageMakerExternalInvokeEndpoint.
Now we want to make a new role SageMakerExternal
Click on Trusted Account and paste child id account here
Add the new policy you just made.
Give it a name.
Now the child account is a trusted entity in the parent account.
What did we just do?
We created a new role SagemakerExternal
that allows us to invoke the specific sagemaker endpoints on this account with the child account as a trusted account.
Now all that is left to do is to assume this role from the child account.
In the child account: Grant assume role to child account
Now what we need to do is get the child account to allow to assume this role.
Then we need to make a lambda to test it and change the execution role of that lambda to allow sts:AssumeRole
.
Log in to child account.
Create new policy AllowAssumeSagemakerExternalRole
This policy will allow the child account to assume this new role.
Give it a nice name
Now create a new lambda.
This is what we want to paste in.
import json
import boto3
import os
from data import body2
def lambda_handler(event, context):
# Assume the cross-account role (allowed because of sts:AssumeRole)
sts_client = boto3.client('sts')
assumed_role = sts_client.assume_role(
RoleArn='arn:aws:iam::<parent account id>:role/SageMakerExternal', # add parent id here
RoleSessionName='SageMakerInvokeSession',
ExternalId='<parent account id>', # add parent id here
)
# Create a new session using the assumed role credentials
credentials = assumed_role['Credentials']
sagemaker_client = boto3.client(
'sagemaker-runtime',
aws_access_key_id=credentials['AccessKeyId'],
aws_secret_access_key=credentials['SecretAccessKey'],
aws_session_token=credentials['SessionToken'],
)
# Add the endpoint you want to call cross-account here
endpoint_name = "f73559-..."
# Invoke the SageMaker endpoint
response = sagemaker_client.invoke_endpoint(
EndpointName=endpoint_name,
ContentType='application/json',
Body=json.dumps({}),
)
# Parse the response
result = json.loads(response['Body'].read().decode())
return {
'statusCode': 200,
'body': json.dumps(result)
}
If you try to run this now you get the following error
“errorMessage”: “An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::
:assumed-role/ is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam:: :role/SageMakerExternal",
What we need to do is change the lambda execution role.
Remember we made this policy: AllowAssumeSagemakerExternalRole
We need to add this policy to the lambda execution role.
Go to the lambda and click on edit.
Go to the bottom and click on edit
Add this piece
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<parent account id>:role/SageMakerExternal"
},
That’s it now you can run cross account sagemaker endpoint requests on AWS!
Conclusion
In this blog posted I showed you how to do cross account Sagemaker requests.
Summary:
- In the parent account with create a policy for invocations and a role with the child account as a trusted account
- In the child account allow that account to assume the role from step 1.
Comments