云成本优化:识别 AWS EBS 卷 “未挂载但计费” 资源的脚本开发与自动清理方案
·
AWS EBS 卷未挂载资源识别与清理方案
问题分析
在 AWS 环境中,EBS 卷处于 "available" 状态时表示未挂载到任何 EC2 实例,但仍在持续计费。这类资源常因运维疏忽导致成本浪费,需通过自动化方案解决:
-
核心识别逻辑
- 状态过滤:
状态 = "available" - 时间阈值:
创建时间 > 保留天数(建议保留窗口 7-30 天) - 标签过滤:排除含
DoNotDelete=true标签的卷
- 状态过滤:
-
风险控制
- 删除前必须创建快照备份
- 关键卷通过标签豁免(如
BackupStrategy=critical) - 操作前发送通知确认
Python 自动化脚本
import boto3
from datetime import datetime, timedelta
def cleanup_orphaned_ebs(region, retention_days, dry_run=True):
ec2 = boto3.client('ec2', region_name=region)
# 获取所有可用状态卷
volumes = ec2.describe_volumes(
Filters=[{'Name': 'status', 'Values': ['available']}]
)['Volumes']
deleted_count = 0
for vol in volumes:
vol_id = vol['VolumeId']
create_time = vol['CreateTime']
# 检查豁免标签
if any(tag['Key'] == 'DoNotDelete' for tag in vol.get('Tags', [])):
print(f"跳过受保护卷: {vol_id}")
continue
# 检查保留期
if datetime.now(create_time.tzinfo) - create_time < timedelta(days=retention_days):
continue
# 创建快照备份
snapshot = ec2.create_snapshot(
VolumeId=vol_id,
Description=f"自动清理备份 {vol_id}"
)
print(f"创建快照: {snapshot['SnapshotId']}")
# 执行删除
if not dry_run:
ec2.delete_volume(VolumeId=vol_id)
print(f"已删除卷: {vol_id}")
deleted_count += 1
else:
print(f"[模拟] 将删除卷: {vol_id}")
return deleted_count
# 示例执行 (实际运行需设置 dry_run=False)
cleanup_orphaned_ebs('us-east-1', retention_days=14)
自动清理架构
graph LR
A[CloudWatch定时触发] --> B[Lambda执行脚本]
B --> C{是否满足删除条件?}
C -->|是| D[创建快照备份]
C -->|否| E[记录审计日志]
D --> F[发送SNS通知]
F --> G[管理员确认窗口]
G -->|无响应| H[删除EBS卷]
G -->|驳回| I[添加豁免标签]
实施建议
-
分阶段部署
- 第一阶段:
dry_run=True运行 7 天,输出审计报告 - 第二阶段:启用 SNS 通知但暂不删除
- 第三阶段:全自动运行
- 第一阶段:
-
监控指标
成本节省 = ∑(已删除卷大小 × 单价 × 闲置天数) 误删防护率 = 1 - (豁免卷数/总可用卷数) -
扩展功能
- 添加 资源归属标签(如
Owner=team@company.com) - 集成 成本中心分配 标签
- 生成 月度优化报告(使用 AWS Cost Explorer API)
- 添加 资源归属标签(如
操作注意:首次运行务必设置
dry_run=True,建议通过 AWS CloudFormation 部署完整方案,确保 IAM 角色仅授予最小必要权限(ec2:DeleteVolume,ec2:CreateSnapshot)。
更多推荐
所有评论(0)