AccessDenied when calling Boto3 assume_role from EC2 even with service principal

Question:

I’m running into an issue when trying to have a Python script running on an EC2 instance assume a role to perform S3 tasks. Here’s what I have done.

  1. Created a IAM role with AmazonS3FullAccess permissions and got the following ARN:

arn:aws:iam::<account_number>:role/<role_name>

The trust policy is set so the principal is a the EC2 service. I interpret this as allowing any EC2 instance within the account being allowed to assume the role.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
  1. I launched an EC2 instance and attached the above IAM role.

  2. I attempt to call assume_role() using Boto3

session = boto3.Session()
sts = session.client("sts")
response = sts.assume_role(
   RoleArn="arn:aws:iam::<account_number>:role/<role_name>",
   RoleSessionName="role_session_name"
)

But it throws the following error:

botocore.exceptions.ClientError: An error occurred (AccessDenied) when
calling the AssumeRole operation: User:
arn:aws:sts::<account_number>:assumed-role/<role_name>/i-<instance_id>
is not authorized to perform: sts:AssumeRole on resource:
arn:aws:iam::<account_number>:role/<role_name>

All other StackOverflow questions about this talk about the Role’s trust policy but mine is set to allow EC2. So either I’m misinterpreting what the policy should be or there is some other error I can’t figure out.

Asked By: barneyAgumble

||

Answers:

You do not have to explicitly call sts.assume_role. If the role is attached to the EC2 instance, boto3 will use in the background seamlessly.You use boto3 as you would normally do, and it will take care of using the IAM role for you. No action required from you.

Answered By: Marcin