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

跨账号Lambda问题:Account A的Lambda获取Account B的EC2实例无结果

跨AWS账号Lambda调用EC2 API返回空结果排查

问题描述:

我尝试用Account A中的Lambda函数获取Account B里的EC2实例,但遇到了问题:

  • Lambda代码能正常运行,Assume Role操作成功返回了访问密钥和会话令牌
  • Account B确实有运行中的EC2实例
  • 调用ec2.describe_instance_status()后返回{'InstanceStatuses': []},没有实例数据
  • Account B的IAM角色已经附加了AmazonEC2ReadOnlyAccess策略,信任关系配置了arn:aws:iam::ACCOUNT_A:role/role-name_ACCOUNT_A

相关代码:

import json
import boto3
from collections import OrderedDict
from pprint import pprint
import time
from time import sleep
from datetime import date
import datetime

def lambda_handler(event, context):
    # Assume Role To connect to other Account
    sts_connection = boto3.client('sts')
    acct_b = sts_connection.assume_role(
        RoleArn="arn:aws:iam::ACCOUNT_B:role/role_name_account_B",
        RoleSessionName="cross_acct_lambda"
    )
    ACCESS_KEY = acct_b['Credentials']['AccessKeyId']
    SECRET_KEY = acct_b['Credentials']['SecretAccessKey']
    SESSION_TOKEN = acct_b['Credentials']['SessionToken']
    
    # create service client using the assumed role credentials, e.g. S3
    ec2 = boto3.client(
        "ec2",
        aws_access_key_id=ACCESS_KEY,
        aws_secret_access_key=SECRET_KEY,
        aws_session_token=SESSION_TOKEN,
    )
    
    status = ec2.describe_instance_status()
    pprint(status)
    
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

执行结果:

Response: {"statusCode": 200, "body": "\"Hello from Lambda!\""}
函数日志:START RequestId: ZZZZZZZZZZZZZZZZZZ Version: $LATEST {'InstanceStatuses': []}


排查方案:

我来帮你一步步梳理可能的原因:

  1. 先明确describe_instance_status的特性
    这个API并不是返回所有EC2实例,它只返回处于运行中(running)状态且已经生成了状态检查数据的实例。如果你的实例是刚启动的,或者处于停止(stopped)/终止(terminated)状态,这个API会直接返回空列表。
    建议先换成describe_instances()测试,这个API会返回所有状态的实例,能帮你快速确认是否真的有权限访问到实例:

    # 替换原来的status = ec2.describe_instance_status()
    instances = ec2.describe_instances()
    pprint(instances)
    
  2. 检查区域是否匹配
    你的Lambda函数默认运行的区域,和Account B中EC2实例所在的区域是不是同一个?boto3的EC2客户端如果没有指定region_name参数,会使用Lambda执行环境的默认区域。如果实例在别的区域,自然查不到任何数据。
    可以在创建EC2客户端时明确指定区域,比如实例在us-east-1:

    ec2 = boto3.client(
        "ec2",
        region_name="us-east-1", # 替换为你的实例所在区域
        aws_access_key_id=ACCESS_KEY,
        aws_secret_access_key=SECRET_KEY,
        aws_session_token=SESSION_TOKEN,
    )
    
  3. 验证信任关系和权限的准确性

    • 确认Account B中IAM角色的信任关系里,Account A的角色ARN完全正确:账号ID、角色名有没有拼写错误?比如是不是误写成了用户ARN而不是角色ARN?
    • 虽然附加了AmazonEC2ReadOnlyAccess,但可以临时在Lambda里加日志打印调用的区域,或者用AssumeRole返回的凭证在本地测试(比如用aws configure set临时配置这些凭证,然后运行aws ec2 describe-instances --region xxx),确认权限是否真的生效。
  4. 再次确认Account B的实例状态
    登录Account B的EC2控制台,确认实例确实处于running状态,没有被停止或终止,而且系统状态和实例状态检查已经显示正常。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 21:17:38