Skip to content

Instantly share code, notes, and snippets.

@Alex-Just
Last active April 12, 2024 14:07
Show Gist options
  • Save Alex-Just/cea96961c37577298e8982c895d4f687 to your computer and use it in GitHub Desktop.
Save Alex-Just/cea96961c37577298e8982c895d4f687 to your computer and use it in GitHub Desktop.
"""
This script retrieves and displays the top five AWS service costs for each of the past six months.
It uses the AWS Cost Explorer API through the AWS CLI to fetch cost data, then processes and
sorts this data to find the most significant service costs. The costs are displayed in USD format,
showing the service name and the incurred cost over each month's period.
Note: AWS CLI must be configured with the appropriate permissions for this script to run successfully.
Sample output:
Period from 2024-02-01 to 2024-02-29:
Amazon Relational Database Service: $1,000.08
Amazon Elastic Compute Cloud - Compute: $400.63
Amazon ElastiCache: $200.23
AWS Transfer Family: $100.60
EC2 - Other: $300.39
Period from 2024-03-01 to 2024-03-31:
...
"""
import json
import subprocess
from datetime import datetime, timedelta
PAST_MONTHS = 6 # including current month
TOP_SERVICES = 5
def get_top_services(start_date, end_date):
result = subprocess.run([
'aws', 'ce', 'get-cost-and-usage',
'--time-period', f'Start={start_date},End={end_date}',
'--granularity', 'MONTHLY',
'--metrics', 'BlendedCost',
'--group-by', 'Type=DIMENSION,Key=SERVICE'
], capture_output=True, text=True)
if result.returncode != 0:
print(f"Error for {start_date} to {end_date}: {result.stderr}")
return []
output = json.loads(result.stdout)
costs = output['ResultsByTime'][0]['Groups']
top_costs = sorted(costs, key=lambda x: float(x['Metrics']['BlendedCost']['Amount']), reverse=True)[:TOP_SERVICES]
return top_costs
def get_month_boundaries(date):
first_day = date.replace(day=1)
next_month = first_day + timedelta(days=31)
last_day = next_month.replace(day=1) - timedelta(days=1)
return first_day, last_day
def to_usd_str(decimal_price):
amount = float(decimal_price or 0)
return f'{"-" if amount < 0 else ""}${abs(amount):,.2f}'.replace('.00', '')
def main():
current_date = datetime.utcnow().date()
for i in range(PAST_MONTHS - 1, -1, -1):
month_to_query = current_date - timedelta(days=current_date.day - 1) - timedelta(days=i * 30)
start_date, end_of_month = get_month_boundaries(month_to_query)
if start_date.month == current_date.month and start_date.year == current_date.year:
end_of_month = current_date
top_services = get_top_services(start_date.strftime("%Y-%m-%d"), end_of_month.strftime("%Y-%m-%d"))
print(f"Period from {start_date} to {end_of_month}:")
for service in top_services:
service_name = service['Keys'][0]
amount = to_usd_str(service['Metrics']['BlendedCost']['Amount'])
print(f" {service_name}: {amount}")
print()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment