mcpField
A
aws-cost-cleanup

aws-cost-cleanup

github.com/sickn33云与 DevOps48.7k104 次安装今天更新
代码仓库

关于 aws-cost-cleanup

aws-cost-cleanup 是用于发现和清理闲置 AWS 资源的自动化技能,适合需要检查云资源浪费的运维人员。它覆盖存储、计算和网络资源,并强调先只读发现、试运行和验证,再执行删除。

主要功能

  1. 01发现多类闲置 AWS 资源
  2. 02生成潜在成本影响报告
  3. 03提供清理脚本和 Lambda 示例
  4. 04按发现、验证、执行和核验组织流程
  5. 05包含删除前安全检查

适用场景

  1. 01查找未挂载的 EBS 卷并评估清理
  2. 02清理过期快照和未完成的 S3 上传
  3. 03检查闲置 EC2、弹性 IP 和网络资源
  4. 04规划跨 AWS 账户的资源检查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill aws-cost-cleanup

安装后在 Claude Code 中输入/aws-cost-cleanup确认已加载。

详细介绍

AWS 成本清理

自动识别并移除未使用的 AWS 资源,消除浪费。

何时使用此技能

需要自动清理未使用的 AWS 资源以降低成本、消除浪费时,请使用此技能。

自动清理目标

存储

  • 未挂载的 EBS 卷
  • 过期的 EBS 快照(>90 天)
  • 未完成的 S3 分段上传
  • 已启用版本控制的存储桶中的旧 S3 版本

计算

  • 已停止的 EC2 实例(>30 天)
  • 未使用的 AMI 及其关联快照
  • 未使用的弹性 IP

网络

  • 未使用的弹性负载均衡器
  • 未使用的 NAT 网关
  • 孤立的 ENI

清理脚本

安全清理(先进行试运行)
#!/bin/bash
# cleanup-unused-ebs.sh

echo "Finding unattached EBS volumes..."
VOLUMES=$(aws ec2 describe-volumes \
  --filters Name=status,Values=available \
  --query 'Volumes[*].VolumeId' \
  --output text)

for vol in $VOLUMES; do
  echo "Would delete: $vol"
  # Uncomment to actually delete:
  # aws ec2 delete-volume --volume-id $vol
done
#!/bin/bash
# cleanup-old-snapshots.sh

CUTOFF_DATE=$(date -d '90 days ago' --iso-8601)

aws ec2 describe-snapshots --owner-ids self \
  --query "Snapshots[?StartTime<='$CUTOFF_DATE'].[SnapshotId,StartTime,VolumeSize]" \
  --output text | while read snap_id start_time size; do
  
  echo "Snapshot: $snap_id (Created: $start_time, Size: ${size}GB)"
  # Uncomment to delete:
  # aws ec2 delete-snapshot --snapshot-id $snap_id
done
#!/bin/bash
# release-unused-eips.sh

aws ec2 describe-addresses \
  --query 'Addresses[?AssociationId==null].[AllocationId,PublicIp]' \
  --output text | while read alloc_id public_ip; do
  
  echo "Would release: $public_ip ($alloc_id)"
  # Uncomment to release:
  # aws ec2 release-address --allocation-id $alloc_id
done
S3 生命周期自动化
# Prepare a lifecycle proposal. This replaces bucket lifecycle configuration;
# retrieve/merge existing rules and scope the prefix before any authorized apply.
cat > lifecycle-policy.json <<EOF
{
  "Rules": [
    {
      "Id": "Archive old objects",
      "Status": "Enabled",
      "Transitions": [
        {
          "Days": 90,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 180,
          "StorageClass": "GLACIER"
        }
      ],
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 30
      },
      "AbortIncompleteMultipartUpload": {
        "DaysAfterInitiation": 7
      }
    }
  ]
}
EOF

# After explicit review only, apply the merged policy to the confirmed bucket.

成本影响计算器

#!/usr/bin/env python3
# calculate-savings.py

import boto3
from datetime import datetime, timedelta

ec2 = boto3.client('ec2')

# Calculate EBS volume savings
volumes = ec2.describe_volumes(
    Filters=[{'Name': 'status', 'Values': ['available']}]
)

total_size = sum(v['Size'] for v in volumes['Volumes'])
monthly_cost = total_size * 0.10  # illustrative input, not a verified gp3 rate

print(f"Unattached EBS Volumes: {len(volumes['Volumes'])}")
print(f"Total Size: {total_size} GB")
print(f"Monthly Savings: ${monthly_cost:.2f}")

# Calculate Elastic IP savings
addresses = ec2.describe_addresses()
unused = [a for a in addresses['Addresses'] if 'AssociationId' not in a]

eip_cost = len(unused) * 3.65  # $0.005/hour * 730 hours
print(f"\nUnused Elastic IPs: {len(unused)}")
print(f"Monthly Savings: ${eip_cost:.2f}")

print(f"\nTotal Monthly Savings: ${monthly_cost + eip_cost:.2f}")
print(f"Annual Savings: ${(monthly_cost + eip_cost) * 12:.2f}")

自动清理 Lambda

import boto3
from datetime import datetime, timedelta

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    
    # Discover candidates only; creation age is not detachment age.
    volumes = ec2.describe_volumes(
        Filters=[{'Name': 'status', 'Values': ['available']}]
    )
    
    cutoff = datetime.now() - timedelta(days=7)
    deleted = 0
    
    for vol in volumes['Volumes']:
        create_time = vol['CreateTime'].replace(tzinfo=None)
        if create_time < cutoff:
            try:
                print(f"Candidate only (not deleted): {vol['VolumeId']}")
            except Exception as e:
                print(f"Error deleting {vol['VolumeId']}: {e}")
    
    return {
        'statusCode': 200,
        'body': 'Dry run only; no volumes deleted'
    }

清理工作流

  1. 发现阶段(只读)

    • 运行所有 describe 命令
    • 生成成本影响报告
    • 与团队审核
  2. 验证阶段

    • 确认资源确实未被使用
    • 检查依赖关系
    • 通知资源所有者
  3. 执行阶段(先进行试运行)

    • 以试运行模式运行清理脚本
    • 审核拟议的变更
    • 执行实际清理
  4. 验证阶段

    • 确认资源已删除
    • 监控是否出现问题
    • 记录节省的成本

安全检查清单

  • 先以试运行模式运行
  • 确认资源没有依赖项
  • 检查资源标签以确认所有权
  • 删除前通知相关方
  • 为关键数据创建快照
  • 先在非生产环境中测试
  • 准备好回滚计划
  • 记录所有删除操作

示例提示词

发现

  • “查找所有未使用的资源并计算潜在节省金额”
  • “为我的 AWS 账户生成清理报告”
  • “哪些资源可以安全删除?”

执行

  • “创建一个清理未挂载 EBS 卷的脚本”
  • “删除所有超过 90 天的快照”
  • “释放未使用的弹性 IP”

自动化

  • “为旧快照设置自动清理”
  • “创建用于每周清理的 Lambda 函数”
  • “安排每月资源清理”

与 AWS Organizations 集成

# Run cleanup across multiple accounts
for account in $(aws organizations list-accounts \
  --query 'Accounts[*].Id' --output text); do
  
  echo "Checking account: $account"
  aws ec2 describe-volumes \
    --filters Name=status,Values=available \
    --profile account-$account
done

监控和提醒

# Create CloudWatch alarm for cost anomalies
aws cloudwatch put-metric-alarm \
  --alarm-name high-cost-alert \
  --alarm-description "Alert when daily cost exceeds threshold" \
  --metric-name EstimatedCharges \
  --namespace AWS/Billing \
  --statistic Maximum \
  --period 86400 \
  --evaluation-periods 1 \
  --threshold 100 \
  --comparison-operator GreaterThanThreshold

最佳实践

  • 在维护时段安排清理
  • 删除前始终创建最终快照
  • 使用资源标签识别待清理对象
  • 为生产环境实施审批工作流
  • 记录所有清理操作以供审计
  • 设置成本异常检测
  • 每周审核清理结果

风险缓解

中风险操作:

  • 删除未挂载的卷(确保没有计划重新挂载)
  • 移除旧快照(确认没有合规要求)
  • 释放弹性 IP(检查 DNS 记录)

始终做到:

  • 保留 30 天备份
  • 对关键资源使用 AWS Backup
  • 测试恢复流程
  • 记录清理决策

Kiro CLI 集成

# Analyze and cleanup in one command
kiro-cli chat "Use aws-cost-cleanup to find and remove unused resources"

# Generate cleanup script
kiro-cli chat "Create a safe cleanup script for my AWS account"

# Schedule automated cleanup
kiro-cli chat "Set up weekly automated cleanup using aws-cost-cleanup"

更多资源

限制

  • 仅当任务明确符合上述范围时,才使用此技能。
  • 不要将输出视为针对特定环境进行验证、测试或专家审核的替代方案。
  • 如果缺少必要的输入、权限、安全边界或成功标准,请停止并请求澄清。

未附加、已停止或较旧的资源仍可能是必需的恢复资产。删除前,应确认账户/区域、所有权、明确的候选 ID、依赖项检查、保留要求以及经过测试的备份/恢复计划。创建时间无法表明卷从何时起不再使用。默认保留试运行;单独获批的执行操作必须重新检查状态/标签和 IAM 范围。在预期的各个区域内分页发现资源,使用当前区域/类型/IOPS/吞吐量/IPv4 定价,并区分预估可避免成本与实际已实现的账单节省额。GNU date -d 在 macOS 上不可移植。

评论

支持 Markdown