aws-cost-analyzer
Skill0 starsChanged 13 months agoMITView on GitHub
AWS cost analysis and optimization for cloud infrastructure analyzing EC2, RDS, S3, Lambda costs
- Installs packages
In this repository16 other files it gives its agents.
- code-reviewerSkill
- dast-scannerSkill
- database-optimizerSkill
- dependency-checkerSkill
- git-workflowSkill
- java-profilerSkill
- jira-integrationSkill
- memory-analyzerSkill
- penetration-testerSkill
- performance-monitorSkill
- python-profilerSkill
- refactoring-assistantSkill
- sast-analyzerSkill
- security-scannerSkill
- skill-validatorSkill
- tdd-workflowSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 504
Right-Size Regularly: Check utilization quarterly
- Distinctive: line 506
Automate Cleanup: Delete unused resources
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AWS Cost Analyzer Skill
Overview
AWS cost analysis and optimization skill for cloud infrastructure. Analyzes costs across services (EC2, RDS, S3, Lambda), identifies unused resources, provides right-sizing recommendations, and optimizes Reserved Instances.
Capabilities
1. Cost Analysis
- Cost breakdown by service
- Cost trends over time
- Cost allocation by project/tag
- Budget vs. actual spending
- Forecasting
2. Resource Optimization
- Unused resource identification
- Right-sizing recommendations
- Reserved Instance optimization
- Savings Plan analysis
- Spot Instance opportunities
3. Storage Optimization
- S3 lifecycle policies
- EBS volume optimization
- Snapshot management
- Intelligent-Tiering setup
4. Monitoring & Alerts
- Cost anomaly detection
- Budget alerts
- Resource utilization tracking
- Cost allocation tags
AWS Cost Explorer CLI
Setup
# Install AWS CLI
brew install awscli # macOS
# Or: pip install awscli
# Configure credentials
aws configure
# Install jq for JSON parsing
brew install jqBasic Cost Queries
# Get total costs for last month
aws ce get-cost-and-usage \
--time-period Start=$(date -d "1 month ago" +%Y-%m-01),End=$(date +%Y-%m-01) \
--granularity MONTHLY \
--metrics BlendedCost \
| jq '.ResultsByTime[].Total.BlendedCost'
# Costs by service (last 30 days)
aws ce get-cost-and-usage \
--time-period Start=$(date -d "30 days ago" +%Y-%m-%d),End=$(date +%Y-%m-%d) \
--granularity MONTHLY \
--metrics BlendedCost \
--group-by Type=DIMENSION,Key=SERVICE \
| jq '.ResultsByTime[].Groups[] | {service: .Keys[0], cost: .Metrics.BlendedCost.Amount}'
# Costs by project tag
aws ce get-cost-and-usage \
--time-period Start=$(date -d "30 days ago" +%Y-%m-%d),End=$(date +%Y-%m-%d) \
--granularity MONTHLY \
--metrics BlendedCost \
--group-by Type=TAG,Key=Project \
| jq '.ResultsByTime[].Groups[]'Cost Optimization Strategies
1. EC2 Right-Sizing
Identify Underutilized Instances:
# Get EC2 instances with CPU utilization < 10%
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--start-time $(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
--period 86400 \
--statistics Average \
| jq '.Datapoints[] | select(.Average < 10)'Right-Sizing Recommendations:
# Example: t3.xlarge → t3.large (save ~50%)
# Current: 4 vCPU, 16 GB RAM, $0.1664/hour
# Recommended: 2 vCPU, 8 GB RAM, $0.0832/hour
# Savings: ~$60/month per instance2. Reserved Instances & Savings Plans
Calculate Potential Savings:
# Get RI recommendations
aws ce get-reservation-purchase-recommendation \
--service "Amazon Elastic Compute Cloud - Compute" \
--lookback-period-in-days SIXTY_DAYS \
--payment-option NO_UPFRONT \
| jq '.Recommendations[] | {
instanceType: .RecommendationDetails.AmazonEC2.InstanceType,
monthlySavings: .RecommendationDetails.EstimatedMonthlySavings,
upfrontCost: .RecommendationDetails.UpfrontCost
}'Typical Savings:
- 1-year RI, No Upfront: ~40% savings
- 3-year RI, All Upfront: ~60% savings
- Compute Savings Plan: ~66% savings
3. S3 Storage Optimization
Lifecycle Policies:
{
"Rules": [
{
"Id": "archive-old-logs",
"Status": "Enabled",
"Filter": {
"Prefix": "logs/"
},
"Transitions": [
{
"Days": 30,
"StorageClass": "STANDARD_IA"
},
{
"Days": 90,
"StorageClass": "GLACIER"
}
],
"Expiration": {
"Days": 365
}
},
{
"Id": "intelligent-tiering",
"Status": "Enabled",
"Filter": {
"Prefix": "data/"
},
"Transitions": [
{
"Days": 0,
"StorageClass": "INTELLIGENT_TIERING"
}
]
}
]
}Apply Lifecycle Policy:
aws s3api put-bucket-lifecycle-configuration \
--bucket siae-dpi-bucket \
--lifecycle-configuration file://lifecycle-policy.jsonStorage Cost Comparison:
| Storage Class | Cost per GB/month | Use Case |
| Standard | $0.023 | Frequently accessed |
| Intelligent-Tiering | $0.023-0.0125 | Unknown access patterns |
| Standard-IA | $0.0125 | Infrequent access |
| Glacier | $0.004 | Archive (3-5 hour retrieval) |
| Glacier Deep Archive | $0.00099 | Long-term archive (12 hour retrieval) |
4. Database (RDS) Optimization
Identify Idle RDS Instances:
# Check database connections
aws cloudwatch get-metric-statistics \
--namespace AWS/RDS \
--metric-name DatabaseConnections \
--dimensions Name=DBInstanceIdentifier,Value=siae-publishing-db \
--start-time $(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
--period 86400 \
--statistics AverageRight-Sizing RDS:
# CPU utilization
aws cloudwatch get-metric-statistics \
--namespace AWS/RDS \
--metric-name CPUUtilization \
--dimensions Name=DBInstanceIdentifier,Value=siae-tunex-db \
--start-time $(date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
--period 86400 \
--statistics Average Maximum
# If Average < 20% and Maximum < 60%, consider downsizing5. Lambda Optimization
Memory Right-Sizing:
# Current: 1024 MB, Average usage: 400 MB
# Recommendation: 512 MB
# Savings: ~50% cost reductionAnalyze Lambda Performance:
# Get Lambda invocations and duration
aws cloudwatch get-metric-statistics \
--namespace AWS/Lambda \
--metric-name Duration \
--dimensions Name=FunctionName,Value=siae-dpi-processor \
--start-time $(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
--period 3600 \
--statistics Average MaximumIntegration Scripts
aws_cost_report.py
Generate comprehensive cost report:
#!/usr/bin/env python3
import boto3
import json
from datetime import datetime, timedelta
def get_monthly_costs():
"""Get costs for current month by service"""
ce = boto3.client('ce', region_name='us-east-1')
start_date = datetime.now().replace(day=1).strftime('%Y-%m-%d')
end_date = datetime.now().strftime('%Y-%m-%d')
response = ce.get_cost_and_usage(
TimePeriod={'Start': start_date, 'End': end_date},
Granularity='MONTHLY',
Metrics=['BlendedCost'],
GroupBy=[{'Type': 'DIMENSION', 'Key': 'SERVICE'}]
)
costs = []
for result in response['ResultsByTime']:
for group in result['Groups']:
service = group['Keys'][0]
cost = float(group['Metrics']['BlendedCost']['Amount'])
if cost > 0:
costs.append({'service': service, 'cost': cost})
return sorted(costs, key=lambda x: x['cost'], reverse=True)
def get_project_costs():
"""Get costs by project tag"""
ce = boto3.client('ce', region_name='us-east-1')
start_date = datetime.now().replace(day=1).strftime('%Y-%m-%d')
end_date = datetime.now().strftime('%Y-%m-%d')
response = ce.get_cost_and_usage(
TimePeriod={'Start': start_date, 'End': end_date},
Granularity='MONTHLY',
Metrics=['BlendedCost'],
GroupBy=[{'Type': 'TAG', 'Key': 'Project'}]
)
costs = []
for result in response['ResultsByTime']:
for group in result['Groups']:
project = group['Keys'][0].split('$')[1] if '$' in group['Keys'][0] else 'Untagged'
cost = float(group['Metrics']['BlendedCost']['Amount'])
if cost > 0:
costs.append({'project': project, 'cost': cost})
return sorted(costs, key=lambda x: x['cost'], reverse=True)
def print_report():
"""Print formatted cost report"""
print("=== AWS Cost Report ===\n")
print(f"Period: {datetime.now().strftime('%B %Y')}\n")
# Service breakdown
print("💰 Costs by Service:")
service_costs = get_monthly_costs()
total = sum(c['cost'] for c in service_costs)
for cost_data in service_costs[:10]:
service = cost_data['service']
cost = cost_data['cost']
percentage = (cost / total * 100) if total > 0 else 0
print(f" {service:40} ${cost:10.2f} ({percentage:5.1f}%)")
print(f"\n {'Total':40} ${total:10.2f}\n")
# Project breakdown
print("📊 Costs by Project:")
project_costs = get_project_costs()
for cost_data in project_costs:
project = cost_data['project']
cost = cost_data['cost']
percentage = (cost / total * 100) if total > 0 else 0
print(f" {project:40} ${cost:10.2f} ({percentage:5.1f}%)")
print("\n=== Top Optimization Opportunities ===")
print("1. Review EC2 instances with <20% CPU utilization")
print("2. Implement S3 lifecycle policies for old data")
print("3. Consider Reserved Instances for steady workloads")
print("4. Enable S3 Intelligent-Tiering for unknown patterns")
print("5. Rightsize RDS instances based on metrics")
if __name__ == '__main__':
print_report()find_unused_resources.py
Identify unused AWS resources:
#!/usr/bin/env python3
import boto3
from datetime import datetime, timedelta
def find_unused_ebs_volumes():
"""Find unattached EBS volumes"""
ec2 = boto3.client('ec2')
volumes = ec2.describe_volumes(
Filters=[{'Name': 'status', 'Values': ['available']}]
)
unused = []
for vol in volumes['Volumes']:
size = vol['Size']
vol_type = vol['VolumeType']
cost_per_gb = 0.10 if vol_type == 'gp3' else 0.10 # Approximate
unused.append({
'id': vol['VolumeId'],
'size': size,
'type': vol_type,
'monthly_cost': size * cost_per_gb
})
return unused
def find_unused_elastic_ips():
"""Find unassociated Elastic IPs"""
ec2 = boto3.client('ec2')
addresses = ec2.describe_addresses()
unused = []
for addr in addresses['Addresses']:
if 'InstanceId' not in addr:
unused.append({
'ip': addr['PublicIp'],
'allocation_id': addr['AllocationId'],
'monthly_cost': 3.60 # $0.005/hour for unused EIP
})
return unused
def find_old_snapshots():
"""Find old EBS snapshots (>90 days)"""
ec2 = boto3.client('ec2')
snapshots = ec2.describe_snapshots(OwnerIds=['self'])
old_snapshots = []
cutoff_date = datetime.now() - timedelta(days=90)
for snap in snapshots['Snapshots']:
start_time = snap['StartTime'].replace(tzinfo=None)
if start_time < cutoff_date:
old_snapshots.append({
'id': snap['SnapshotId'],
'size': snap['VolumeSize'],
'age_days': (datetime.now() - start_time).days,
'monthly_cost': snap['VolumeSize'] * 0.05
})
return old_snapshots
def generate_cleanup_report():
"""Generate resource cleanup report"""
print("=== Unused AWS Resources Report ===\n")
# EBS Volumes
print("💾 Unattached EBS Volumes:")
volumes = find_unused_ebs_volumes()
if volumes:
for vol in volumes:
print(f" {vol['id']}: {vol['size']}GB {vol['type']} - ${vol['monthly_cost']:.2f}/month")
total_vol_cost = sum(v['monthly_cost'] for v in volumes)
print(f" Total potential savings: ${total_vol_cost:.2f}/month\n")
else:
print(" ✅ No unused volumes found\n")
# Elastic IPs
print("🌐 Unassociated Elastic IPs:")
eips = find_unused_elastic_ips()
if eips:
for eip in eips:
print(f" {eip['ip']} ({eip['allocation_id']}) - ${eip['monthly_cost']:.2f}/month")
total_eip_cost = sum(e['monthly_cost'] for e in eips)
print(f" Total potential savings: ${total_eip_cost:.2f}/month\n")
else:
print(" ✅ No unused EIPs found\n")
# Old Snapshots
print("📸 Old EBS Snapshots (>90 days):")
snapshots = find_old_snapshots()
if snapshots:
for snap in snapshots[:10]:
print(f" {snap['id']}: {snap['size']}GB, {snap['age_days']} days old - ${snap['monthly_cost']:.2f}/month")
if len(snapshots) > 10:
print(f" ... and {len(snapshots) - 10} more")
total_snap_cost = sum(s['monthly_cost'] for s in snapshots)
print(f" Total potential savings: ${total_snap_cost:.2f}/month\n")
else:
print(" ✅ No old snapshots found\n")
# Summary
total_savings = (
sum(v['monthly_cost'] for v in volumes) +
sum(e['monthly_cost'] for e in eips) +
sum(s['monthly_cost'] for s in snapshots)
)
print(f"=== Total Potential Monthly Savings: ${total_savings:.2f} ===")
print(f"=== Annual Savings: ${total_savings * 12:.2f} ===")
if __name__ == '__main__':
generate_cleanup_report()rightsize_recommendations.sh
Generate EC2 right-sizing recommendations:
#!/bin/bash
# EC2 right-sizing recommendations
echo "=== EC2 Right-Sizing Analysis ==="
echo
# Get all running instances
aws ec2 describe-instances \
--filters "Name=instance-state-name,Values=running" \
--query 'Reservations[].Instances[].[InstanceId,InstanceType,Tags[?Key==`Name`].Value|[0]]' \
--output text | while read instance_id instance_type name; do
echo "Analyzing: $name ($instance_id - $instance_type)"
# Get average CPU utilization (last 7 days)
cpu_avg=$(aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=$instance_id \
--start-time $(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%S) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
--period 86400 \
--statistics Average \
--query 'Datapoints[].Average' \
--output text | awk '{sum+=$1; count++} END {if(count>0) print sum/count; else print 0}')
# Recommendation logic
if (( $(echo "$cpu_avg < 10" | bc -l) )); then
echo " ⚠️ CPU: ${cpu_avg}% - Consider stopping or downsizing"
elif (( $(echo "$cpu_avg < 30" | bc -l) )); then
echo " ⚠️ CPU: ${cpu_avg}% - Consider downsizing"
elif (( $(echo "$cpu_avg > 80" | bc -l) )); then
echo " ⚠️ CPU: ${cpu_avg}% - Consider upsizing"
else
echo " ✅ CPU: ${cpu_avg}% - Well-sized"
fi
echo
doneBest Practices
- Tag All Resources: Enable cost allocation tracking
- Set Budgets: Alert at 80% and 100% of budget
- Monthly Reviews: Analyze costs every month
- Right-Size Regularly: Check utilization quarterly
- Use Savings Plans: For predictable workloads
- Automate Cleanup: Delete unused resources
- Enable Cost Anomaly Detection: Catch spikes early
- Optimize Storage: Lifecycle policies for all S3 buckets
- Monitor Trends: Track cost per user/transaction
- Document Decisions: Why resources are provisioned
Requirements
# AWS CLI
pip install awscli boto3
# Configure
aws configure
# Set permissions (IAM policy):
# - ce:GetCostAndUsage
# - ec2:Describe*
# - cloudwatch:GetMetricStatistics
# - s3:List*Cost Optimization Checklist
- [ ] EC2 instances right-sized
- [ ] Reserved Instances purchased for steady workloads
- [ ] S3 lifecycle policies configured
- [ ] Unattached EBS volumes deleted
- [ ] Unused Elastic IPs released
- [ ] Old snapshots cleaned up
- [ ] RDS instances right-sized
- [ ] Lambda memory optimized
- [ ] CloudWatch log retention set (7-30 days)
- [ ] Cost allocation tags applied
- [ ] Budget alerts configured
- [ ] Cost anomaly detection enabledMetrics to Track
- Monthly cost: Trending down or flat
- Cost per user: Improving efficiency
- Unused resources: Minimal (<5%)
- RI/SP coverage: > 60% for predictable workloads
- Storage costs: Optimized with lifecycle policies
- Compute utilization: 40-70% average
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

