Rrun python3 main.py to generate the report
Copy
import boto3
from datetime import datetime
import sys
import os
def get_ce_data(client, start_date, end_date, group_by):
results = []
next_token = None
while True:
params = {
'TimePeriod': {'Start': start_date, 'End': end_date},
'Granularity': 'MONTHLY',
'Metrics': ['UnblendedCost'],
'GroupBy': group_by
}
if next_token:
params['NextPageToken'] = next_token
response = client.get_cost_and_usage(**params)
results.extend(response['ResultsByTime'])
next_token = response.get('NextPageToken')
if not next_token:
break
return results
def get_cost_report(start_date, end_date):
client = boto3.client('ce', region_name='us-east-1')
print(f"Fetching cost data from {start_date} to {end_date}...")
try:
# Query 1: Service and UsageType (To map UsageType to Service)
print("Mapping UsageTypes to Services...")
results_service_usage = get_ce_data(client, start_date, end_date, [
{'Type': 'DIMENSION', 'Key': 'SERVICE'},
{'Type': 'DIMENSION', 'Key': 'USAGE_TYPE'}
])
usage_to_service = {}
for month in results_service_usage:
for group in month['Groups']:
service = group['Keys'][0]
usage_type = group['Keys'][1]
usage_to_service[usage_type] = service
# Query 2: UsageType and Name (The per-resource breakdown)
print("Querying per-resource costs (UsageType + Name)...")
results_usage_name = get_ce_data(client, start_date, end_date, [
{'Type': 'DIMENSION', 'Key': 'USAGE_TYPE'},
{'Type': 'TAG', 'Key': 'Name'}
])
# Prepare Report Content
report_date = datetime.now().strftime("%Y-%m-%d")
filename = f"Report-{report_date}.md"
header = f"| {'Resource tag Name':<45} | {'AWS Service Name':<35} | {'Service Type (UsageType)':<55} | {'Cost (USD)':<10} |"
separator = f"| {'-'*45} | {'-'*35} | {'-'*55} | {'-'*10} |"
lines = []
lines.append(f"# AWS Detailed Cost Report - {start_date} to {end_date}")
lines.append(f"Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
lines.append(header)
lines.append(separator)
total_cost = 0.0
all_groups = []
for month in results_usage_name:
for group in month['Groups']:
usage_type = group['Keys'][0]
name_tag = group['Keys'][1].replace("Name$", "") or "Untagged"
cost = float(group['Metrics']['UnblendedCost']['Amount'])
service = usage_to_service.get(usage_type, "Unknown Service")
all_groups.append({
'name': name_tag,
'service': service,
'usage_type': usage_type,
'cost': cost
})
# Sort by cost descending
all_groups.sort(key=lambda x: x['cost'], reverse=True)
for item in all_groups:
if item['cost'] > 0.01:
line = f"| {item['name']:<45} | {item['service']:<35} | {item['usage_type']:<55} | ${item['cost']:>9.2f} |"
lines.append(line)
total_cost += item['cost']
footer_sep = f"| {'-'*45} | {'-'*35} | {'-'*55} | {'-'*10} |"
footer = f"| {'TOTAL':<45} | {'':<35} | {'':<55} | ${total_cost:>9.2f} |"
lines.append(footer_sep)
lines.append(footer)
# Write to file
with open(filename, 'w') as f:
f.write('\n'.join(lines))
print(f"\nDetailed report generated: {filename}")
print(f"Total Cost: ${total_cost:.2f}")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
# Define the period
START = "2026-02-01"
END = "2026-03-08"
get_cost_report(START, END)
