跨AWS账号通过ECS部署API启停EC2实例的IAM权限报错问题
问题根因及排查解决步骤
1. 核心问题修复:代码未执行跨账号角色扮演
你当前的boto3代码直接初始化EC2客户端,默认使用的是BBB账号ECS任务角色本身的权限,没有主动扮演AAA账号的ec2-instance-mgmt-role,所有请求默认发往BBB账号的EC2服务,自然没有权限访问AAA账号的资源,这是报错的最主要原因。
修正后的代码片段如下,需要先调用STS接口获取AAA账号角色的临时凭证,再用临时凭证初始化EC2客户端:
import boto3 # 第一步:用ECS任务角色默认权限调用STS,扮演AAA账号的管理角色 sts_client = boto3.client('sts') assume_role_response = sts_client.assume_role( RoleArn="arn:aws:iam::AAA:role/ec2-instance-mgmt-role", # 替换为AAA账号实际角色ARN RoleSessionName="ecs-ec2-mgmt-session" ) # 第二步:用返回的临时凭证初始化EC2客户端 credentials = assume_role_response['Credentials'] ec2 = boto3.client( 'ec2', region_name=region_name, aws_access_key_id=credentials['AccessKeyId'], aws_secret_access_key=credentials['SecretAccessKey'], aws_session_token=credentials['SessionToken'] ) # 后续的实例状态查询、启停逻辑保持原有写法即可
2. IAM配置校验项
如果修复代码后仍报错,按以下顺序核对配置:
- 账号AAA侧角色信任关系校验
确认ec2-instance-mgmt-role的信任策略中,正确填写了BBB的账号ID,信任实体为AWS账号类型,参考正确配置如下:
如果信任策略中添加了外部ID、MFA等限制条件,需要在{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::BBB:root" }, "Action": "sts:AssumeRole" } ] }assume_role调用时传入对应参数,否则会被拦截。 - 账号BBB侧ECS任务角色权限校验
确认绑定给ECS任务的角色确实附加了ec2-assume-managerole策略,且策略中的AAA账号ID、目标角色ARN拼写完全正确,没有字符错误。 - 实例标签校验
确认你要操作的AAA账号EC2实例,已经打上了ManagedBy=API的标签,大小写完全匹配,否则启停接口会被策略的条件规则拦截。 - 权限边界校验
确认两个账号的对应角色都没有附加限制跨账号访问的权限边界策略,如有需要同步放开对应操作权限。
3. 辅助排查手段
如果仍有问题,可以在代码中开启boto3的debug日志,查看实际请求使用的凭证、请求发往的账号ID,快速定位权限问题:
import logging boto3.set_stream_logger('', logging.DEBUG)
内容的提问来源于stack exchange,提问作者erase.ego
相关产品推荐
相关产品推荐

