Search code examples
pythonamazon-web-servicesboto3assume-role

how to assume roles twice (or multiple times) in the script


I am trying to assume a role twice in the script, I assume the role first like this

import boto3 session = boto3.Session(profile_name="learnaws-test")
sts = session.client("sts")
response = sts.assume_role(
RoleArn="arn:aws:iam::xxx:role/s3-readonly-access",
RoleSessionName="learnaws-test-session"
)
new_session = Session(aws_access_key_id=response['Credentials']['AccessKeyId'], aws_secret_access_key=response['Credentials']['SecretAccessKey'], aws_session_token=response['Credentials']['SessionToken'])

but after I have done this, I understand I can use this new_session to access s3 buckets or whatever resourse and stuff but I need to assume another role from this role, how do I assume another role?

logically, I think from this "new_session" we have to do something to assume another role, but what is it?


Solution

  • Call AssumeRole

    When calling AssumeRole(), a new set of credentials is returned. You can then use these credentials to create new clients, including another Security Token Service (STS) client that can be used to call AssumeRole() again.

    Here is an example:

    import boto3
    
    # Create STS client using default credentials
    
    sts_client = boto3.client('sts')
    
    # Assume Role 1
    
    response1 = sts_client.assume_role(RoleArn='arn:aws:iam::111111111111:role/assume1', RoleSessionName='One')
    
    credentials1 = response1['Credentials']
    
    role1_session = boto3.Session(
        aws_access_key_id=credentials1['AccessKeyId'],
        aws_secret_access_key=credentials1['SecretAccessKey'],
        aws_session_token=credentials1['SessionToken'])
    
    sts_client1 = role1_session.client('sts')
    
    # Assume Role 2
    
    response2 = sts_client1.assume_role(RoleArn='arn:aws:iam::111111111111:role/assume2', RoleSessionName='Two')
    
    credentials2 = response2['Credentials']
    
    role2_session = boto3.Session(
        aws_access_key_id=credentials2['AccessKeyId'],
        aws_secret_access_key=credentials2['SecretAccessKey'],
        aws_session_token=credentials2['SessionToken'])
    
    # Use Role 2
    
    s3_client2 = role2_session.client('s3')
    
    response = s3_client2.list_buckets()
    
    print(response)
    

    Use profiles

    However, there is an easier way to do this using profiles. You can configure the ~/.aws/config file to assume roles automatically:

    [default]
    region = ap-southeast-2
    
    [profile role1]
    role_arn=arn:aws:iam::111111111111:role/assume1
    source_profile=default
    
    [profile role2]
    role_arn=arn:aws:iam::111111111111:role/assume2
    source_profile=role1
    

    This is telling boto3:

    • When assuming role1, use the default credentials
    • When assuming role2, use credentials from role1

    Assuming both roles is then as simple as:

    import boto3
    
    session = boto3.Session(profile_name='role2')
    s3_client = session.client('s3')
    
    response = s3_client.list_buckets()
    
    print(response)
    

    This also works with the AWS CLI:

    aws s3 ls --profile role2
    

    For more information, see: Credentials — Boto3 documentation