Skip to main content

Rrun python3 main.py to generate the report

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)