From this article, you will learn about Cross-account IAM, how to use IAM role from another AWS account. IAM roles are a powerful tool for managing access to AWS resources, but they can be difficult to set up and use. Today I will show you how a lambda function can use an IAM role from another AWS account.
In one AWS account, you can create a lambda function and assign a IAM role, just like you always do. However, you can create a new IAM role in a completely different AWS account and let the lambda function use it. You can control another AWS account using the Lambda function. For this article, I will be using Python 3.10 and boto3.
First IAM role(lambda01-role
)
In the first AWS account(Account A) I will create IAM Role lambda01-role
and function lambda lambda01
. I will only give the lambda function minimal permissions to control the role named read-role-all-account on any AWS account.
You should normally create a IAM role as always and add the following permissions to it:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam:::role/read-role-all-account"
}
]
}
In my case, the read-role-all-account
role will be created in the second AWS account(Account B). I want to manage this IAM role. In ARN, you can leave the slot blank or add a wildcard, so you can manage this role for each account. If you want to be more precise, you can only allow control of one account, then enter the account number in place of the asterisks.
Second IAM role(read-role-all-account
)
Now log in to the AWS account you want to manage, in my case Account B. Here you need to create a new IAM role you want to manage with the name you set earlier. In my case it is read-role-all-account
.
Add the permissions you need to this IAM role. I only want to read data about ec2, so the following permissions are enough for me. You add what you need.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:Describe*",
"Resource": "*"
}
]
}
Once you have created the IAM role, you should edit the trust recationship and specify more precisely which role, from which AWS account you will allow to manage this IAM role.
VERY IMPORTANT specify what role, from which AWS account you trust and let it control that IAM role. Don’t use * here for account number or role name, because you will allow anyone to use this role.
I will write this again because it is very important. Specify the exact role name and account number that will be able to use this role. In my case it looks like this.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT_ID:role/lambda01-role"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
Remember to replace ACCOUNT_ID
with your AWS account ID.
Lambda Function(lambda01
)
Now that you have created the IAM roles, you can start creating lambda function. When creating the lambda function lambda01
, I assigned the IAM role lambda01-role
to the function. Just for the record, this IAM role is in the same account as the Lambda function and only there.
In the function code, I will be using the read-role-all-account
role that is on those AWS accounts that I want to control. Below you will find the lambda function code that allows you to use the IAM role from another AWS account and returns information about the AMIs used.
import boto3
def lambda_handler(event, context):
regions = ['us-east-1', 'eu-central-1']
ami_ids = list()
sts_connection = boto3.client('sts')
account_b = sts_connection.assume_role(
RoleArn="arn:aws:iam::ACCOUNT_ID:role/read-role-all-account",
RoleSessionName="cross_account_lambda"
)
AWS_ACCOUNT_ACCESS_KEY = account_b['Credentials']['AccessKeyId']
AWS_ACCOUNT_SECRET_KEY = account_b['Credentials']['SecretAccessKey']
AWS_ACCOUNT_TOKEN = account_b['Credentials']['SessionToken']
print("Read information from account B, from many regions")
for region in regions:
ec2_client = boto3.client(
'ec2',
region,
aws_access_key_id=AWS_ACCOUNT_ACCESS_KEY,
aws_secret_access_key=AWS_ACCOUNT_SECRET_KEY,
aws_session_token=AWS_ACCOUNT_TOKEN,
)
describe_instance = ec2_client.describe_instances()
for reservation in describe_instance["Reservations"]:
if reservation:
for instance in reservation["Instances"]:
ami_ids.append(instance["ImageId"])
print("InstanceId: " + instance["InstanceId"] + " AMI_Id: " + instance["ImageId"] + " Region: " + region)
return(ami_ids)
Remember to replace ACCOUNT_ID
with your AWS account ID
In the video, at the top of the page or on YouTube, you will find a step-by-step tutorial on how to implement such a solution with cross-account IAM role.
I encourage you to watch and subscribe to the channel.
Summary
As you have seen, managing IAM roles from another AWS account is not all that difficult. Cross-Account IAM is certainly something every DevOps should know and be able to use. If the topic is still giving you problems, I encourage you to watch my video where you will find more details.
If you don’t have several AWS accounts, don’t worry. You can share the IAM role in the same AWS account. Let AWS only have permission to control another IAM role in the same account. Just remember to add the appropriate permissions in the controlled role.
I also encourage you to read other articles, e.g. 7 ways to delete data from S3.