Skip to content

rchamoli/azure-cost-optimizer

Repository files navigation

πŸ’° Azure Cost Optimizer

CI Python Azure License Code style: ruff

An intelligent Python tool that analyzes your Azure subscription, identifies cost-saving opportunities, and provides actionable recommendations. Save up to 40% on your Azure bill with automated insights.

Azure Cost Optimizer Demo

✨ Features

Feature Description
πŸ“Š Comprehensive Cost Analysis Analyze spending by resource group, service, and location
πŸ’‘ Smart Recommendations AI-driven suggestions for cost optimization
πŸ“ˆ Trend Analysis Track spending trends and predict future costs
🎨 Visual Reports Generate PDF, Excel, and JSON reports
πŸ“§ Automated Alerts Email notifications for budget overruns
πŸ”„ Scheduled Scans Continuous monitoring with configurable schedules
🐳 Docker Support Run anywhere with containerized deployment

Optimization Categories

  • πŸ–₯️ Idle Resources: Find unused VMs, disks, and public IPs
  • πŸ“ Right-sizing: Identify oversized VMs based on actual metrics
  • πŸ’΅ Reserved Instances: Calculate savings with RI purchases
  • πŸ’Ύ Storage Optimization: Detect expensive storage tiers
  • πŸ—‘οΈ Snapshot Cleanup: Identify outdated snapshots and backups
  • πŸ—„οΈ Database Optimization: Find idle or oversized SQL databases

πŸš€ Quick Start

Prerequisites

  • Python 3.11+ (Download)
  • Azure subscription with Cost Management access
  • Azure CLI or Service Principal credentials

Installation

# Clone repository
git clone https://github.com/rchamoli/azure-cost-optimizer.git
cd azure-cost-optimizer

# Create virtual environment
python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate

# Install package
pip install -e .

# Or install with development dependencies
pip install -e ".[dev]"

Configuration

# Copy environment template
cp .env.example .env

# Edit with your Azure credentials
nano .env  # or use your preferred editor

Required environment variables:

AZURE_SUBSCRIPTION_ID=your-subscription-id
AZURE_TENANT_ID=your-tenant-id
AZURE_CLIENT_ID=your-client-id
AZURE_CLIENT_SECRET=your-client-secret

πŸ’‘ Tip: You can also use Azure CLI authentication. If logged in via az login, credentials are picked up automatically.

Usage

# Basic analysis with console output
python cost_optimizer.py analyze

# Or use the installed CLI
azure-cost-optimizer analyze

# Analyze specific resource group
azure-cost-optimizer analyze --resource-group myResourceGroup

# Generate PDF report
azure-cost-optimizer analyze --format pdf --output report.pdf

# Analyze last 90 days
azure-cost-optimizer analyze --days 90

# Send report via email
azure-cost-optimizer analyze --email

# Validate Azure connection
azure-cost-optimizer validate

# Show current configuration
azure-cost-optimizer config

πŸ“Š Sample Output

Console Output

╔════════════════════════════════════════════════════════════╗
β•‘           Azure Cost Optimization Report                   β•‘
β•‘                  January 2024                              β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

πŸ“Š Cost Summary:
   Current Month:     $15,234.56
   Previous Month:    $14,890.23
   Change:            +2.3% ($344.33)
   Projected (EOY):   $182,814.72

πŸ’‘ Potential Savings: $4,521.00 per month (29.7%)

🎯 Top Recommendations:

1. Stop Idle Virtual Machines (8 found)
   πŸ’° Estimated Savings: $1,840/month
   πŸ“ Resources: vm-dev-01, vm-test-03, vm-staging-02...

2. Delete Unattached Disks (15 found)
   πŸ’° Estimated Savings: $325/month

3. Right-size Oversized VMs (5 found)
   πŸ’° Estimated Savings: $1,156/month

4. Purchase Reserved Instances
   πŸ’° Estimated Savings: $1,200/month

πŸ—οΈ Project Structure

azure-cost-optimizer/
β”œβ”€β”€ src/azure_cost_optimizer/    # Main package
β”‚   β”œβ”€β”€ analyzers/               # Cost analysis modules
β”‚   β”‚   β”œβ”€β”€ compute.py           # VM and disk analysis
β”‚   β”‚   β”œβ”€β”€ storage.py           # Storage analysis
β”‚   β”‚   β”œβ”€β”€ network.py           # Network analysis
β”‚   β”‚   └── database.py          # Database analysis
β”‚   β”œβ”€β”€ recommenders/            # Recommendation engines
β”‚   β”‚   └── reserved_instances.py
β”‚   β”œβ”€β”€ reporters/               # Report generators
β”‚   β”‚   β”œβ”€β”€ console.py           # Terminal output
β”‚   β”‚   β”œβ”€β”€ pdf.py               # PDF generation
β”‚   β”‚   β”œβ”€β”€ excel.py             # Excel export
β”‚   β”‚   └── email.py             # Email reports
β”‚   β”œβ”€β”€ utils/                   # Utilities
β”‚   β”‚   β”œβ”€β”€ azure_client.py      # Azure SDK wrapper
β”‚   β”‚   β”œβ”€β”€ cost_calculator.py   # Cost calculations
β”‚   β”‚   └── metrics.py           # Metrics collection
β”‚   β”œβ”€β”€ cli.py                   # CLI commands
β”‚   β”œβ”€β”€ config.py                # Configuration
β”‚   β”œβ”€β”€ models.py                # Data models
β”‚   └── optimizer.py             # Main orchestrator
β”œβ”€β”€ tests/                       # Test suite
β”œβ”€β”€ .github/workflows/           # CI/CD pipelines
β”œβ”€β”€ pyproject.toml               # Project configuration
β”œβ”€β”€ Dockerfile                   # Container image
└── docker-compose.yml           # Docker Compose setup

βš™οΈ Configuration

All configuration is done via environment variables. See .env.example for the full list.

Core Settings

Variable Description Default
AZURE_SUBSCRIPTION_ID Azure subscription to analyze Required
AZURE_TENANT_ID Azure AD tenant ID Optional*
AZURE_CLIENT_ID Service principal client ID Optional*
AZURE_CLIENT_SECRET Service principal secret Optional*
ANALYSIS_DAYS Days to analyze 30
DEFAULT_OUTPUT_FORMAT Output format console

*Optional if using Azure CLI authentication

Threshold Settings

Variable Description Default
IDLE_VM_CPU_PERCENT CPU % to consider VM idle 5
IDLE_VM_DAYS Days of idle before flagging 7
SNAPSHOT_AGE_DAYS Age to flag old snapshots 90
MIN_SAVINGS_THRESHOLD Minimum savings to report 10

Email Settings

Variable Description Default
EMAIL_ENABLED Enable email reports false
SMTP_SERVER SMTP server hostname smtp.gmail.com
SMTP_PORT SMTP port 587
EMAIL_FROM Sender email address -
EMAIL_TO Recipients (comma-separated) -

🐳 Docker Deployment

Build and Run

# Build image
docker build -t azure-cost-optimizer .

# Run analysis
docker run --env-file .env azure-cost-optimizer analyze

# Generate PDF report (mount volume for output)
docker run --env-file .env -v $(pwd)/reports:/app/reports \
  azure-cost-optimizer analyze --format pdf --output /app/reports/report.pdf

Docker Compose

# Run one-time analysis
docker compose run --rm optimizer analyze

# Start scheduled analyzer (weekly)
docker compose --profile scheduled up -d scheduler

πŸ§ͺ Development

Setup

# Install with dev dependencies
pip install -e ".[dev]"

# Install pre-commit hooks
pre-commit install

Testing

# Run all tests
pytest

# Run with coverage
pytest --cov=src/azure_cost_optimizer --cov-report=html

# Run specific test file
pytest tests/test_models.py -v

Linting & Formatting

# Run linter
ruff check src/ tests/

# Auto-fix issues
ruff check --fix src/ tests/

# Format code
ruff format src/ tests/

# Type checking
mypy src/azure_cost_optimizer

πŸ” Security

Required Azure Permissions

The service principal needs these roles:

Role Purpose
Cost Management Reader Read cost data
Reader Read resource metadata
Monitoring Reader Read performance metrics

Grant Permissions

# Create service principal with required roles
az ad sp create-for-rbac --name "cost-optimizer-sp" \
  --role "Cost Management Reader" \
  --scopes /subscriptions/{subscription-id}

# Assign additional roles
az role assignment create \
  --assignee {service-principal-id} \
  --role "Reader" \
  --scope /subscriptions/{subscription-id}

az role assignment create \
  --assignee {service-principal-id} \
  --role "Monitoring Reader" \
  --scope /subscriptions/{subscription-id}

Security Best Practices

  • βœ… Never commit .env or credentials to git
  • βœ… Use Azure Managed Identity in production
  • βœ… Rotate service principal secrets regularly
  • βœ… Use least-privilege access (read-only roles)
  • βœ… Enable audit logging for the service principal
  • βœ… Store secrets in Azure Key Vault for production

🚒 Production Deployment

Production Checklist

  • Use Azure Managed Identity instead of service principal secrets
  • Deploy to Azure Container Instances or Azure Functions
  • Enable Azure Monitor for container logs
  • Set up budget alerts in Azure Cost Management
  • Configure email notifications for stakeholders
  • Schedule weekly/monthly analysis runs
  • Store reports in Azure Blob Storage
  • Enable RBAC for report access

Azure Container Instance Deployment

# Deploy to ACI
az container create \
  --resource-group myResourceGroup \
  --name cost-optimizer \
  --image ghcr.io/rchamoli/azure-cost-optimizer:latest \
  --assign-identity \
  --restart-policy OnFailure \
  --environment-variables \
    AZURE_SUBSCRIPTION_ID=your-sub-id \
    LOG_LEVEL=INFO

Azure Functions Deployment

# Deploy as Azure Function (timer-triggered)
func azure functionapp publish YourFunctionApp

πŸ”§ Troubleshooting

Common Issues

Authentication Failed
Error: DefaultAzureCredential failed to retrieve a token

Solutions:

  1. Verify Azure CLI is logged in: az account show
  2. Check service principal credentials in .env
  3. Ensure tenant ID is correct
  4. Run azure-cost-optimizer validate to test connection
Cost Data Unavailable
Warning: Cost Management API access limited

Solutions:

  1. Ensure Cost Management Reader role is assigned
  2. Cost data may take 24-48 hours to appear for new subscriptions
  3. Check if Cost Management is enabled for the subscription
No Recommendations Found

Possible causes:

  1. All resources are already optimized
  2. Metrics data not available (wait 7+ days)
  3. Thresholds too strict - adjust in .env
  4. Resource group filter too narrow

πŸ“ˆ Programmatic Usage

from azure_cost_optimizer import CostOptimizer

# Create optimizer instance
optimizer = CostOptimizer(subscription_id="your-sub-id")

# Run analysis
result = optimizer.analyze(days=30)

# Get recommendations
recommendations = optimizer.get_recommendations(limit=10)

# Calculate total savings
total_savings = optimizer.calculate_potential_savings()
print(f"Potential savings: ${total_savings}/month")

# Generate reports
optimizer.generate_report(format="pdf", output="report.pdf")
optimizer.generate_report(format="json", output="data.json")

# Export to JSON
optimizer.export_to_json("analysis.json")

# Send email report
optimizer.send_email(attachment_format="pdf")

# Clean up
optimizer.close()

πŸ›£οΈ Roadmap

  • Multi-subscription support
  • AWS and GCP cost analysis
  • Machine learning for anomaly detection
  • Slack/Teams integration
  • Custom policies and rules engine
  • Historical trend analysis (12+ months)
  • What-if scenario modeling
  • Integration with Azure DevOps
  • Terraform cost estimation
  • Real-time cost alerts

🀝 Contributing

Contributions are welcome! Please see our Contributing Guide for details.

Areas Needing Help

  • Additional analyzers for Azure services (AKS, App Service, etc.)
  • Enhanced visualization options
  • Performance optimizations
  • Documentation improvements
  • Integration tests

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ‘€ Author

Rahul Chamoli - Cloud Engineer & Cost Optimization Specialist


πŸ™ Acknowledgments

  • Azure Cost Management Team
  • Python Azure SDK contributors
  • Open-source reporting libraries (ReportLab, Pandas, Rich)

πŸ“š Resources


πŸ’° Save money, optimize resources, sleep better!

⭐ Star this repo if it helps you reduce your Azure costs!

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •