{
  "schema": "https://ai-atoms.com/schemas/skill-v1.json",
  "type": "skill",
  "id": "skill/aws-cost-cleanup",
  "version": "1.0.0",
  "name": "Aws Cost Cleanup",
  "description": "Automated cleanup of unused AWS resources to reduce costs",
  "system_prompt_fragment": "# AWS Cost Cleanup\n\nAutomate the identification and removal of unused AWS resources to eliminate waste.\n\n## When to Use This Skill\n\nUse this skill when you need to automatically clean up unused AWS resources to reduce costs and eliminate waste.\n\n## Automated Cleanup Targets\n\n**Storage**\n- Unattached EBS volumes\n- Old EBS snapshots (>90 days)\n- Incomplete multipart S3 uploads\n- Old S3 versions in versioned buckets\n\n**Compute**\n- Stopped EC2 instances (>30 days)\n- Unused AMIs and associated snapshots\n- Unused Elastic IPs\n\n**Networking**\n- Unused Elastic Load Balancers\n- Unused NAT Gateways\n- Orphaned ENIs\n\n## Cleanup Scripts\n\n### Safe Cleanup (Dry-Run First)\n\n```bash\n#!/bin/bash\n# cleanup-unused-ebs.sh\n\necho \"Finding unattached EBS volumes...\"\nVOLUMES=$(aws ec2 describe-volumes \\\n  --filters Name=status,Values=available \\\n  --query 'Volumes[*].VolumeId' \\\n  --output text)\n\nfor vol in $VOLUMES; do\n  echo \"Would delete: $vol\"\n  # Uncomment to actually delete:\n  # aws ec2 delete-volume --volume-id $vol\ndone\n```\n\n```bash\n#!/bin/bash\n# cleanup-old-snapshots.sh\n\nCUTOFF_DATE=$(date -d '90 days ago' --iso-8601)\n\naws ec2 describe-snapshots --owner-ids self \\\n  --query \"Snapshots[?StartTime<='$CUTOFF_DATE'].[SnapshotId,StartTime,VolumeSize]\" \\\n  --output text | while read snap_id start_time size; do\n  \n  echo \"Snapshot: $snap_id (Created: $start_time, Size: ${size}GB)\"\n  # Uncomment to delete:\n  # aws ec2 delete-snapshot --snapshot-id $snap_id\ndone\n```\n\n```bash\n#!/bin/bash\n# release-unused-eips.sh\n\naws ec2 describe-addresses \\\n  --query 'Addresses[?AssociationId==null].[AllocationId,PublicIp]' \\\n  --output text | while read alloc_id public_ip; do\n  \n  echo \"Would release: $public_ip ($alloc_id)\"\n  # Uncomment to release:\n  # aws ec2 release-address --allocation-id $alloc_id\ndone\n```\n\n### S3 Lifecycle Automation\n\n```bash\n# Apply lifecycle policy to transition old objects to cheaper storage\ncat > lifecycle-policy.json <<EOF\n{\n  \"Rules\": [\n    {\n      \"Id\": \"Archive old objects\",\n      \"Status\": \"Enabled\",\n      \"Transitions\": [\n        {\n          \"Days\": 90,\n          \"StorageClass\": \"STANDARD_IA\"\n        },\n        {\n          \"Days\": 180,\n          \"StorageClass\": \"GLACIER\"\n        }\n      ],\n      \"NoncurrentVersionExpiration\": {\n        \"NoncurrentDays\": 30\n      },\n      \"AbortIncompleteMultipartUpload\": {\n        \"DaysAfterInitiation\": 7\n      }\n    }\n  ]\n}\nEOF\n\naws s3api put-bucket-lifecycle-configuration \\\n  --bucket my-bucket \\\n  --lifecycle-configuration file://lifecycle-policy.json\n```\n\n## Cost Impact Calculator\n\n```python\n#!/usr/bin/env python3\n# calculate-savings.py\n\nimport boto3\nfrom datetime import datetime, timedelta\n\nec2 = boto3.client('ec2')\n\n# Calculate EBS volume savings\nvolumes = ec2.describe_volumes(\n    Filters=[{'Name': 'status', 'Values': ['available']}]\n)\n\ntotal_size = sum(v['Size'] for v in volumes['Volumes'])\nmonthly_cost = total_size * 0.10  # $0.10/GB-month for gp3\n\nprint(f\"Unattached EBS Volumes: {len(volumes['Volumes'])}\")\nprint(f\"Total Size: {total_size} GB\")\nprint(f\"Monthly Savings: ${monthly_cost:.2f}\")\n\n# Calculate Elastic IP savings\naddresses = ec2.describe_addresses()\nunused = [a for a in addresses['Addresses'] if 'AssociationId' not in a]\n\neip_cost = len(unused) * 3.65  # $0.005/hour * 730 hours\nprint(f\"\\nUnused Elastic IPs: {len(unused)}\")\nprint(f\"Monthly Savings: ${eip_cost:.2f}\")\n\nprint(f\"\\nTotal Monthly Savings: ${monthly_cost + eip_cost:.2f}\")\nprint(f\"Annual Savings: ${(monthly_cost + eip_cost) * 12:.2f}\")\n```\n\n## Automated Cleanup Lambda\n\n```python\nimport boto3\nfrom datetime import datetime, timedelta\n\ndef lambda_handler(event, context):\n    ec2 = boto3.client('ec2')\n    \n    # Delete unattached volumes older than 7 days\n    volumes = ec2.describe_volumes(\n        Filters=[{'Name': 'status', 'Values': ['available']}]\n    )\n    \n    cutoff = datetime.now() - timedelta(days=7)\n    deleted = 0\n    \n    for vol in volumes['Volumes']:\n        create_time = vol['CreateTime'].replace(tzinfo=None)\n        if create_time < cutoff:\n            try:\n                ec2.delete_volume(VolumeId=vol['VolumeId'])\n                deleted += 1\n                print(f\"Deleted volume: {vol['VolumeId']}\")\n            except Exception as e:\n                print(f\"Error deleting {vol['VolumeId']}: {e}\")\n    \n    return {\n        'statusCode': 200,\n        'body': f'Deleted {deleted} volumes'\n    }\n```\n\n## Cleanup Workflow\n\n1. **Discovery Phase** (Read-only)\n   - Run all describe commands\n   - Generate cost impact report\n   - Review with team\n\n2. **Validation Phase**\n   - Verify resources are truly unused\n   - Check for dependencies\n   - Notify resource owners\n\n3. **Execution Phase** (Dry-run first)\n   - Run cleanup scripts with dry-run\n   - Review proposed changes\n   - Execute actual cleanup\n\n4. **Verification Phase**\n   - Confirm deletions\n   - Monitor for issues\n   - Document savings\n\n## Safety Checklist\n\n- [ ] Run in dry-run mode first\n- [ ] Verify resources have no dependencies\n- [ ] Check resource tags for ownership\n- [ ] Notify stakeholders before deletion\n- [ ] Create snapshots of critical data\n- [ ] Test in non-production first\n- [ ] Have rollback plan ready\n- [ ] Document all deletions\n\n## Example Prompts\n\n**Discovery**\n- \"Find all unused resources and calculate potential savings\"\n- \"Generate a cleanup report for my AWS account\"\n- \"What resources can I safely delete?\"\n\n**Execution**\n- \"Create a script to cleanup unattached EBS volumes\"\n- \"Delete all snapshots older than 90 days\"\n- \"Release unused Elastic IPs\"\n\n**Automation**\n- \"Set up automated cleanup for old snapshots\"\n- \"Create a Lambda function for weekly cleanup\"\n- \"Schedule monthly resource cleanup\"\n\n## Integration with AWS Organizations\n\n```bash\n# Run cleanup across multiple accounts\nfor account in $(aws organizations list-accounts \\\n  --query 'Accounts[*].Id' --output text); do\n  \n  echo \"Checking account: $account\"\n  aws ec2 describe-volumes \\\n    --filters Name=status,Values=available \\\n    --profile account-$account\ndone\n```\n\n## Monitoring and Alerts\n\n```bash\n# Create CloudWatch alarm for cost anomalies\naws cloudwatch put-metric-alarm \\\n  --alarm-name high-cost-alert \\\n  --alarm-description \"Alert when daily cost exceeds threshold\" \\\n  --metric-name EstimatedCharges \\\n  --namespace AWS/Billing \\\n  --statistic Maximum \\\n  --period 86400 \\\n  --evaluation-periods 1 \\\n  --threshold 100 \\\n  --comparison-operator GreaterThanThreshold\n```\n\n## Best Practices\n\n- Schedule cleanup during maintenance windows\n- Always create final snapshots before deletion\n- Use resource tags to identify cleanup candidates\n- Implement approval workflow for production\n- Log all cleanup actions for audit\n- Set up cost anomaly detection\n- Review cleanup results weekly\n\n## Risk Mitigation\n\n**Medium Risk Actions:**\n- Deleting unattached volumes (ensure no planned reattachment)\n- Removing old snapshots (verify no compliance requirements)\n- Releasing Elastic IPs (check DNS records)\n\n**Always:**\n- Maintain 30-day backup retention\n- Use AWS Backup for critical resources\n- Test restore procedures\n- Document cleanup decisions\n\n## Kiro CLI Integration\n\n```bash\n# Analyze and cleanup in one command\nkiro-cli chat \"Use aws-cost-cleanup to find and remove unused resources\"\n\n# Generate cleanup script\nkiro-cli chat \"Create a safe cleanup script for my AWS account\"\n\n# Schedule automated cleanup\nkiro-cli chat \"Set up weekly automated cleanup using aws-cost-cleanup\"\n```\n\n## Additional Resources\n\n- [AWS Resource Cleanup Best Practices](https://aws.amazon.com/blogs/mt/automate-resource-cleanup/)\n- [AWS Systems Manager Automation](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-automation.html)\n- [AWS Config Rules for Compliance](https://docs.aws.amazon.com/config/latest/developerguide/managed-rules-by-aws-config.html)",
  "applicable_domains": [
    "devops"
  ],
  "category": "devops",
  "invocation": [
    "/aws-cost-cleanup"
  ],
  "authored_by": "claudeskills.in community",
  "source_url": "https://claudeskills.in/skill/aws-cost-cleanup",
  "provenance": {
    "source": "claudeskills.in",
    "source_url": "https://claudeskills.in/skill/aws-cost-cleanup",
    "license": "unknown",
    "imported_at": "2026-09-03",
    "notes": "Aggregated by claudeskills.in from community GitHub lists."
  },
  "tags": [
    "claudeskills",
    "devops",
    "risk-reviewed"
  ],
  "lifecycle": "draft"
}