I recently had a need for a management server running in one account to assume a role in another AWS account. This way I didn’t have to deploy the management server in every single AWS account. All that’s required to achieve this are IAM roles with the right permissions

This is what we are going to do:
- Create an IAM ec2 instance Profile in Account A with assume role permissions to the IAM Account in B
- Create an IAM role in Account B with a trust relationship that allows the IAM role created in Account A
Account A:
Let’s create an ec2 instance profile with the following inline permissions policy attached. This will allow the IAM role to assume the role (that we will create in the next step) in Account B. You can add whatever permissions you may want for this instance profile to have in Account A
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::Account_B:role/Account_B_IAM_Role"
]
}
]
}
Attach this ec2 instance profile to your application server running in Account A.
Account B:
Create an IAM role “Account_B_IAM_Role” with the following inline policy and trust relationship. For the sake of this example, I’m going to give it read only access to EC2.
AWS Managed Policy:arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
Trust Relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::Account_A:role/Account_A_IAM_Role"
],
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
What we have done above is created an IAM Role in Account B and have given access to the IAM role created in Account A to assume this role
To test if this is working, I have a nifty shell script that I run on the server. I save this as “assume-account-b-role.sh” and place this in /usr/bin
read -r secret_access_key session_token access_key_id <<<$(aws sts assume-role --role-arn "arn:aws:iam::Account_B:role/Account_B_IAM_Role" --role-session-name "switch_to_account_B" | jq -r '.Credentials.secret_access_key, .Credentials.session_token, .Credentials.access_key_id') ;
export AWS_SECRET_ACCESS_KEY="$secret_access_key"
export AWS_SESSION_TOKEN="$session_token"
export AWS_ACCESS_KEY_ID="$access_key_id"
To assume the role, I simply run source assume-account-b-role.sh and that’s it. This server running in Account A has read only permissions to EC2 in Account B.