You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Boto3和Python创建AWS MFA授权会话并跨账号获取EC2实例

Solution: MFA-Authorized Cross-Account EC2 Instance Retrieval with Boto3

Based on your scenario with three linked AWS accounts (main for IAM management, acc1/acc2 for EC2), here's a step-by-step implementation to meet your requirements:


Prerequisites

  • Boto3 installed (pip install boto3)
  • MFA enabled for your main account IAM user
  • Cross-account roles created in aws_acc_1 and aws_acc_2 that trust your main account (with a condition requiring MFA)
  • Your main account user has permission to assume these cross-account roles

Step 1: Configure AWS Credentials & Config Files

First, set up your .aws/credentials and .aws/config files to streamline profile management:

.aws/credentials

Store your main account's IAM user credentials here:

[aws_acc_main]
aws_access_key_id = YOUR_MAIN_ACCOUNT_ACCESS_KEY
aws_secret_access_key = YOUR_MAIN_ACCOUNT_SECRET_KEY

.aws/config

Define profiles for each sub-account, linking to the cross-account role and MFA device:

[profile aws_acc_1]
role_arn = arn:aws:iam::YOUR_ACC1_ACCOUNT_ID:role/CrossAccountEC2ReadOnlyRole
source_profile = aws_acc_main
mfa_serial = arn:aws:iam::YOUR_MAIN_ACCOUNT_ID:mfa/YourMainUserMFA
region = us-east-1  # Replace with your target region

[profile aws_acc_2]
role_arn = arn:aws:iam::YOUR_ACC2_ACCOUNT_ID:role/CrossAccountEC2ReadOnlyRole
source_profile = aws_acc_main
mfa_serial = arn:aws:iam::YOUR_MAIN_ACCOUNT_ID:mfa/YourMainUserMFA
region = us-west-2  # Replace with your target region

Note: The cross-account roles should have a trust policy requiring MFA, and attach the AmazonEC2ReadOnlyAccess managed policy (or a custom policy with ec2:DescribeInstances permission).


Step 2: Create MFA-Authorized Session (test1.py)

This script handles MFA authentication and returns a Boto3 session using the assumed cross-account role:

import boto3
from botocore.exceptions import ClientError

def get_assumed_role_session(account_profile: str, mfa_token: str):
    """Create a Boto3 session using an MFA-authenticated cross-account role"""
    try:
        # Initialize base session from the profile
        base_session = boto3.Session(profile_name=account_profile)
        sts_client = base_session.client('sts')
        
        # Extract role ARN and MFA serial from profile config
        profile_config = base_session._session.get_scoped_config()
        role_arn = profile_config['role_arn']
        mfa_serial = profile_config['mfa_serial']
        
        # Assume the role with MFA validation
        sts_response = sts_client.assume_role(
            RoleArn=role_arn,
            RoleSessionName=f"MFA-Session-{account_profile}",
            SerialNumber=mfa_serial,
            TokenCode=mfa_token
        )
        
        # Create session with temporary credentials
        assumed_session = boto3.Session(
            aws_access_key_id=sts_response['Credentials']['AccessKeyId'],
            aws_secret_access_key=sts_response['Credentials']['SecretAccessKey'],
            aws_session_token=sts_response['Credentials']['SessionToken'],
            region_name=profile_config.get('region', 'us-east-1')
        )
        
        return assumed_session
    except ClientError as e:
        print(f"Error assuming role: {e.response['Error']['Message']}")
        raise

Step 3: Fetch EC2 Instances from Sub-Accounts (test2.py)

Use the authenticated session to retrieve and display EC2 instances from both sub-accounts:

from test1 import get_assumed_role_session

def list_ec2_instances(assumed_session):
    """List all EC2 instances in the assumed session's region"""
    ec2_client = assumed_session.client('ec2')
    try:
        response = ec2_client.describe_instances()
        for reservation in response['Reservations']:
            for instance in reservation['Instances']:
                print(f"Instance ID: {instance['InstanceId']}")
                print(f"  State: {instance['State']['Name']}")
                print(f"  Instance Type: {instance['InstanceType']}")
                print(f"  Launch Time: {instance['LaunchTime']}\n")
    except ClientError as e:
        print(f"Error fetching EC2 instances: {e.response['Error']['Message']}")
        raise

if __name__ == "__main__":
    # Get MFA token from user input
    mfa_token = input("Enter your MFA token (6 digits): ").strip()
    
    # Fetch instances from aws_acc_1
    print("=== EC2 Instances in aws_acc_1 ===")
    acc1_session = get_assumed_role_session('aws_acc_1', mfa_token)
    list_ec2_instances(acc1_session)
    
    # Fetch instances from aws_acc_2
    print("\n=== EC2 Instances in aws_acc_2 ===")
    acc2_session = get_assumed_role_session('aws_acc_2', mfa_token)
    list_ec2_instances(acc2_session)

Key Notes

  • Temporary credentials from assume_role are valid for up to 12 hours (adjust with the DurationSeconds parameter if needed)
  • Add error handling for edge cases (invalid MFA token, missing permissions, etc.)
  • The main account only needs IAM permissions to assume cross-account roles—no other service access is required

内容的提问来源于stack exchange,提问作者wafers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:27:42