AWS Lambda孤儿快照查询函数输出异常且跨账号运行报错
问题解决思路
一、修复快照及标签的输出格式问题
你的代码直接打印snapshot对象会输出boto3的实例字符串,格式不友好,且标签处理逻辑存在漏洞(比如快照无tags属性时会报错),可以按以下方式修改代码:
import boto3 def lambda_handler(event, context): ec2_resource = boto3.resource('ec2') # 获取所有云硬盘ID volumes = [vol.volume_id for vol in ec2_resource.volumes.all()] # 获取当前账号的快照 snapshots = ec2_resource.snapshots.filter(OwnerIds=['self']) orphaned_snapshots = [] for snap in snapshots: # 判断是否为孤儿快照(关联的硬盘不存在) if snap.volume_id not in volumes: # 提取快照关键信息 snap_info = { "snapshot_id": snap.snapshot_id, "volume_id": snap.volume_id, "start_time": str(snap.start_time), "description": snap.description, "tags": snap.tags if snap.tags else [] } orphaned_snapshots.append(snap_info) # 格式化打印快照信息 print(f"\n孤儿快照ID: {snap.snapshot_id}") print(f"关联硬盘ID: {snap.volume_id}") print(f"创建时间: {snap.start_time}") # 处理标签 if snap.tags: name_tag = next((tag['Value'] for tag in snap.tags if tag['Key'] == 'Name'), '无名称标签') print(f"名称标签: {name_tag}") print(f"所有标签: {snap.tags}") else: print("无标签") print(f"\n总计孤儿快照数量: {len(orphaned_snapshots)}") # 返回结构化数据给调用方 return { "statusCode": 200, "orphaned_snapshots": orphaned_snapshots }
修改点说明:
- 提取快照的
snapshot_id、start_time等具体字段,替代打印整个对象 - 处理快照无
tags的场景,避免遍历标签时抛出异常 - 用
next()快速定位Name标签,简化代码逻辑 - 返回结构化JSON数据,方便后续对接其他系统
二、解决跨AWS账号运行报错的问题
不同账号运行出错,优先排查以下几个方向:
1. IAM权限差异
即使你认为配置了相同权限,也要确认Lambda角色的权限策略是否包含以下必要权限:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:DescribeVolumes", "ec2:DescribeSnapshots" ], "Resource": "*" } ] }
另外检查是否存在AWS组织的SCP(服务控制策略),这类策略可能在组织层面限制EC2相关操作,导致权限失效。
2. 快照数据异常
部分账号可能存在特殊快照:比如无关联volume_id的快照(手动创建的空快照、共享后未关联硬盘的快照),此时snap.volume_id为None,可能触发逻辑异常。可以在代码中增加判断:
if snap.volume_id is None or snap.volume_id not in volumes: # 标记为孤儿快照并处理
3. Lambda运行环境的boto3版本差异
不同AWS区域或账号的Lambda默认boto3版本可能不同,旧版本对EC2资源的属性返回逻辑可能存在差异。可以在代码开头打印版本排查:
print("boto3版本:", boto3.__version__)
若版本过低,可通过Lambda层添加指定版本的boto3进行升级。
4. 资源区域限制
确认两个账号的Lambda函数是否部署在同一区域,或代码是否显式指定区域。未指定区域时,boto3会使用Lambda所在区域的默认配置,若某账号在该区域无EC2资源,可能触发异常。可以显式指定区域:
ec2_resource = boto3.resource('ec2', region_name='us-east-1')
内容的提问来源于stack exchange,提问作者Cloud Wanderer
相关产品推荐
相关产品推荐

