Die Oberfläche ist lokalisiert; Skill-Beschreibungen und -Dokumente werden per KI automatisch in Ihre Sprache übersetzt. Code, Befehle, Pfade und Fachbegriffe bleiben im Original, maßgeblich ist das Dokument des Autors.
Skills entdecken
Daten und Forschung · SKILL.md

cost-optimization-analysis

cost-optimization-analysis

Cloud cost optimization analysis including AWS Cost Explorer, Azure Cost Management, and GCP Billing with right-sizing recommendations and optimization strategies for multi-cloud environments

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill-Dokumentation

GitHub

name: cost-optimization-analysis compatibility: opencode completeness: 95 content-types:

  • guidance
  • examples
  • do-dont
  • config description: Cloud cost optimization analysis including AWS Cost Explorer, Azure Cost Management, and GCP Billing with right-sizing recommendations and optimization strategies for multi-cloud environments license: MIT maturity: stable metadata: domain: cncf output-format: code related-skills: agent-database-admin, cncf-cost-optimization, cncf-kubernetes-debugging role: implementation scope: implementation triggers: aws cost explorer, azure cost analysis, gcp billing, cloud cost optimization, right-sizing recommendations, spot instance strategy, reserved instance optimization, cost allocation archetypes:
    • tactical anti_triggers:
    • brainstorming
    • vague ideation
    • non-containerized architecture response_profile: verbosity: low directive_strength: high abstraction_level: operational version: "1.0.0"

Cloud Cost Optimization Analysis

Implements comprehensive multi-cloud cost optimization strategies including AWS Cost Explorer analysis, Azure Cost Management analysis, GCP Billing analysis, right-sizing recommendations, spot instance optimization, reserved instance planning, and cost allocation frameworks. This skill enables data-driven decisions to reduce cloud infrastructure costs while maintaining performance and reliability.

TL;DR Checklist

  • Collect and normalize cost data from all cloud providers using their respective APIs and CLI tools
  • Identify idle and underutilized resources (right-sizing candidates)
  • Analyze spot instance eligibility and implement spot placement strategies
  • Plan reserved instance purchases based on historical usage patterns
  • Implement cost allocation tagging and chargeback models
  • Set up automated alerts for budget thresholds and anomalies
  • Optimize storage tiers based on access patterns
  • Document optimization recommendations and track ROI

When to Use

Use this skill when:

  • Conducting a cloud cost optimization audit across AWS, Azure, and GCP environments
  • Identifying idle or underutilized resources for right-sizing decisions
  • Planning spot instance adoption to reduce compute costs by 50-90%
  • Evaluating reserved instance or savings plan eligibility based on usage patterns
  • Implementing cost allocation frameworks for chargeback/showback models
  • Investigating unexpected cost spikes and anomalies in cloud billing
  • Designing multi-cloud cost optimization strategies with unified visibility
  • Reviewing storage tier assignments and lifecycle policies

When NOT to Use

Avoid this skill for:

  • Real-time cost monitoring — Use dedicated cost monitoring tools like Datadog Cloud Cost Management or AWS Cost and Usage Report (CUR) for real-time dashboards instead
  • Budget approval workflows — This skill provides analysis and recommendations but not the budget approval process; use financial governance tools for approvals
  • Contract negotiation — While this skill identifies optimization opportunities, actual vendor contract negotiation requires procurement expertise
  • Infrastructure design — Use cncf-infrastructure-as-code for designing new infrastructure; cost optimization should follow design completion
  • Security compliance — Cost optimization may impact security configurations; always validate against security requirements using cncf-security-compliance skill
  • Emergency cost reduction — For immediate budget cuts, use emergency kill-switches rather than optimization workflows; this skill is for strategic, sustainable savings

Core Workflow

  1. Data Collection — Gather cost data from AWS Cost Explorer, Azure Cost Management, and GCP Billing APIs. Checkpoint: Verify all cost data is normalized to a common currency (USD) and time period.

  2. Resource Discovery — Identify all resources (EC2, Azure VMs, GCP Compute Engine) with usage and cost data. Checkpoint: Ensure resource IDs are standardized across providers for multi-cloud correlation.

  3. Idle Resource Analysis — Analyze CPU, memory, network, and storage utilization metrics to identify underutilized resources. Checkpoint: Confirm utilization data covers at least 14 days to account for weekly patterns.

  4. Right-Sizing Recommendations — Generate right-sizing recommendations based on utilization thresholds (e.g., CPU < 30% for 2 weeks). Checkpoint: Validate recommendations against application SLAs and performance requirements.

  5. Spot Instance Strategy — Evaluate workload characteristics for spot instance eligibility (fault-tolerant, stateless, interruptible workloads). Checkpoint: Confirm spot instance savings projections account for interruption rates and replacement costs.

  6. Cost Allocation Framework — Implement tagging strategy and cost allocation models for chargeback/showback. Checkpoint: Ensure all resources have required cost allocation tags (owner, project, environment, cost-center).


Implementation Patterns

Pattern 1: AWS Cost Explorer Analysis

AWS Cost Explorer provides detailed cost and usage data. Use the AWS CLI to analyze costs by service, tag, and time period.

BAD — Hardcoded date range without error handling

# ❌ BAD — No error checking, hardcoded dates, no output formatting
aws ce get-cost-and-usage \
  --time-period Start=2024-01-01,End=2024-02-01 \
  --granularity DAILY \
  --metrics UnblendedCost \
  --group-by Type=DIMENSION Key=SERVICE

GOOD — Robust script with error handling and formatting

#!/bin/bash
# ✅ GOOD — Proper error handling, dynamic dates, JSON output
set -euo pipefail

START_DATE="${START_DATE:-$(date -d '1 month ago' +%Y-%m-%d)}"
END_DATE="${END_DATE:-$(date +%Y-%m-%d)}"

aws ce get-cost-and-usage \
  --time-period "Start=${START_DATE},End=${END_DATE}" \
  --granularity MONTHLY \
  --metrics UnblendedCost \
  --group-by "Type=DIMENSION,Key=SERVICE" \
  --query 'ResultsByTime[].Total[].UnblendedCost Amount' \
  --output text | awk '{sum += $1} END {printf "Total Monthly Cost: $%.2f\n", sum}'

Python SDK Alternative

# ✅ GOOD — Python SDK with proper pagination
import boto3
from datetime import datetime, timedelta

def get_aws_cost_by_service(days: int = 30) -> dict:
    """Get AWS cost breakdown by service for the specified number of days."""
    client = boto3.client('ce', region_name='us-east-1')
    
    end_date = datetime.utcnow().date()
    start_date = end_date - timedelta(days=days)
    
    response = client.get_cost_and_usage(
        TimePeriod={
            'Start': start_date.isoformat(),
            'End': end_date.isoformat()
        },
        Granularity='MONTHLY',
        Metrics=['UnblendedCost'],
        GroupBy=[{'Type': 'DIMENSION', 'Key': 'SERVICE'}]
    )
    
    return {
        'service_costs': {
            group['Keys'][0]: float(result['Total']['UnblendedCost']['Amount'])
            for result in response['ResultsByTime'][-1]['Groups']
            for group in result['Groups']
        },
        'total_cost': float(response['ResultsByTime'][-1]['Total']['UnblendedCost']['Amount'])
    }

# Usage example
costs = get_aws_cost_by_service(days=30)
for service, cost in costs['service_costs'].items():
    print(f"{service}: ${cost:.2f}")
print(f"Total: ${costs['total_cost']:.2f}")

Pattern 2: Azure Cost Management Analysis

Azure Cost Management provides detailed cost data through the Azure CLI and REST API.

BAD — Direct API call without authentication

# ❌ BAD — Missing authentication, no pagination handling
curl https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.CostManagement/query?api-version=2022-10-01

GOOD — Azure CLI with proper authentication and formatting

#!/bin/bash
# ✅ GOOD — Azure CLI with authentication, filtering, and formatting
set -euo pipefail

# Login if not already authenticated
az account show >/dev/null 2>&1 || az login

SUBSCRIPTION_ID=$(az account show --query id -o tsv)
START_DATE="2024-01-01"
END_DATE="2024-12-31"

# Query cost data by resource group
az costmanagement query \
  --type "Usage" \
  --timeframe "MonthToDate" \
  --dataset-aggregation '{"totalCost":{"name":"PreTaxCost","function":"Sum"}}' \
  --dataset-grouping '{"name":"ResourceGroup","type":"Dimension"}' \
  --subscription "$SUBSCRIPTION_ID" \
  --query "properties.rows[]" \
  --output tsv

ARM Template Cost Analysis

# ✅ GOOD — Estimate costs from ARM template deployments
az deployment sub what-if \
  --template-file "arm-template.json" \
  --parameters "parameters.json" \
  --location "eastus" \
  --query "properties.cost" \
  --output table

Python SDK for Azure Cost Analysis

# ✅ GOOD — Azure Cost Management SDK with proper error handling
from azure.identity import DefaultAzureCredential
from azure.mgmt.costmanagement import CostManagementClient
from datetime import datetime, timedelta

def get_azure_cost_by_resource_group(days: int = 30) -> dict:
    """Get Azure cost breakdown by resource group."""
    subscription_id = os.getenv("AZURE_SUBSCRIPTION_ID")
    if not subscription_id:
        raise ValueError("AZURE_SUBSCRIPTION_ID environment variable not set")
    
    credential = DefaultAzureCredential()
    client = CostManagementClient(credential, subscription_id)
    
    end_date = datetime.utcnow().date()
    start_date = end_date - timedelta(days=days)
    
    body = {
        "type": "Usage",
        "timeframe": "Custom",
        "time_period": {
            "from": start_date.isoformat(),
            "to": end_date.isoformat()
        },
        "dataset": {
            "granularity": "Daily",
            "grouping": [{"type": "Dimension", "name": "ResourceGroup"}]
        }
    }
    
    try:
        result = client.query.usage(scope=f"subscriptions/{subscription_id}", parameters=body)
        
        return {
            "resource_group_costs": {
                item.name: item.properties.total_cost
                for item in result.properties.rows
            },
            "total_cost": sum(item.properties.total_cost for item in result.properties.rows)
        }
    except Exception as e:
        print(f"Error fetching Azure costs: {e}")
        return {}

# Usage
costs = get_azure_cost_by_resource_group(days=30)
print(f"Total Azure Cost: ${costs.get('total_cost', 0):.2f}")

Pattern 3: GCP Billing Analysis

Google Cloud Billing provides cost data through the Cloud Billing API and gcloud CLI.

BAD — Simple API call without error handling

# ❌ BAD — No error handling, missing authentication
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://billingaccount.googleapis.com/v1/billingAccounts"

GOOD — GCP CLI with proper authentication and cost analysis

#!/bin/bash
# ✅ GOOD — GCP CLI with authentication and cost analysis
set -euo pipefail

gcloud auth print-access-token >/dev/null 2>&1 || gcloud auth login

BILLING_ACCOUNT=$(gcloud billing accounts list --format="value(name)" | head -1)

# Get costs by project for the last 30 days
gcloud billing budgets describe \
  --billing-account="$BILLING_ACCOUNT" \
  --format="value(name)" 2>/dev/null || true

# Alternative: Use Cloud Billing Export to BigQuery for detailed analysis
gcloud bigquery queries run \
  "SELECT 
    project.name as project_name,
    service.description as service,
    SUM(cost) as total_cost
  FROM 
    \`\${BILLING_ACCOUNT}.billing_data.gcp_billing_export_v1_012345\`
  WHERE 
    _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  GROUP BY 
    project.name, service.description
  ORDER BY 
    total_cost DESC
  LIMIT 20" \
  --format="table"

Python SDK for GCP Cost Analysis

# ✅ GOOD — GCP Billing SDK with proper error handling and pagination
from google.cloud import billing_v1
from google.api_core.exceptions import GoogleAPICallError
from datetime import datetime, timedelta
import os

def get_gcp_cost_by_project(days: int = 30) -> dict:
    """Get GCP cost breakdown by project."""
    billing_account_id = os.getenv("GCP_BILLING_ACCOUNT_ID")
    if not billing_account_id:
        raise ValueError("GCP_BILLING_ACCOUNT_ID environment variable not set")
    
    client = billing_v1.CloudBillingClient()
    
    # Get billing account name
    billing_account_name = f"billingAccounts/{billing_account_id}"
    
    # Get cost data from BigQuery export (recommended approach)
    # This assumes Cloud Billing Export is configured to BigQuery
    bigquery_client = bigquery.Client()
    
    query = f"""
    SELECT 
      project.name as project_name,
      service.description as service,
      SUM(cost) as total_cost,
      COUNT(DISTINCT sku.id) as sku_count
    FROM 
      `{billing_account_id}.billing_data.gcp_billing_export_v1_012345`
    WHERE 
      _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL {days} DAY)
    GROUP BY 
      project.name, service.description
    ORDER BY 
      total_cost DESC
    """
    
    try:
        query_job = bigquery_client.query(query)
        results = query_job.result()
        
        project_costs = {}
        for row in results:
            if row.project_name not in project_costs:
                project_costs[row.project_name] = 0.0
            project_costs[row.project_name] += row.total_cost
        
        return {
            "project_costs": project_costs,
            "total_cost": sum(project_costs.values()),
            "services": list(set(row.service for row in results))
        }
    except GoogleAPICallError as e:
        print(f"GCP API Error: {e}")
        return {}
    except Exception as e:
        print(f"Error fetching GCP costs: {e}")
        return {}

# Usage
os.environ["GCP_BILLING_ACCOUNT_ID"] = "012345-567890-ABCDEF"
costs = get_gcp_cost_by_project(days=30)
print(f"Total GCP Cost: ${costs.get('total_cost', 0):.2f}")

Pattern 4: Right-Sizing Recommendations

Right-sizing analysis identifies resources that are over-provisioned or under-provisioned.

BAD — Simple threshold without context

# ❌ BAD — No context, no history, no action plan
for instance in $(aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId' --output text); do
  cpu=$(aws cloudwatch get-metric-statistics --metric-name CPUUtilization --dimensions InstanceId=$instance --start-time 2024-01-01 --end-time 2024-01-02 --period 86400 --statistics Average --query 'Datapoints[].Average' --output text)
  echo "$instance CPU: $cpu"
done

GOOD — Comprehensive right-sizing analysis script

#!/bin/bash
# ✅ GOOD — Comprehensive right-sizing with historical analysis and recommendations
set -euo pipefail

REGION="${AWS_REGION:-us-east-1}"
DAYS_ANALYZED="${DAYS_ANALYZED:-14}"
CPU_THRESHOLD_LOW=30
CPU_THRESHOLD_HIGH=80

echo "=== Right-Sizing Analysis ==="
echo "Region: $REGION"
echo "Analysis Period: $DAYS_ANALYZED days"
echo "Low CPU Threshold: ${CPU_THRESHOLD_LOW}%"
echo "High CPU Threshold: ${CPU_THRESHOLD_HIGH}%"
echo ""

# Get all running instances
instances=$(aws ec2 describe-instances \
  --filters "Name=instance-state-name,Values=running" \
  --query 'Reservations[].Instances[].{InstanceId:InstanceId,InstanceType:InstanceType,Tags:Tags}' \
  --region "$REGION" \
  --output json)

# Analyze each instance
echo "$instances" | jq -c '.Reservations[].Instances[]' | while read -r instance; do
  instance_id=$(echo "$instance" | jq -r '.InstanceId')
  current_type=$(echo "$instance" | jq -r '.InstanceType')
  
  # Get CPU utilization data
  cpu_avg=$(aws cloudwatch get-metric-statistics \
    --metric-name CPUUtilization \
    --dimensions Name=InstanceId,Value=$instance_id \
    --start-time $(date -d "$DAYS_ANALYZED days ago" +%Y-%m-%dT%H:%M:%S) \
    --end-time $(date +%Y-%m-%dT%H:%M:%S) \
    --period 86400 \
    --statistics Average \
    --output json | jq -r '.Datapoints[].Average' | awk '{sum+=$1} END {printf "%.1f", sum/NR}')
  
  # Get memory utilization (requires CloudWatch Agent)
  memory_avg=$(aws cloudwatch get-metric-statistics \
    --metric-name MemoryUtilization \
    --namespace AWS/ECS \
    --dimensions Name=ClusterName,Value=default Name=ServiceName,Value=none \
    --start-time $(date -d "$DAYS_ANALYZED days ago" +%Y-%m-%dT%H:%M:%S) \
    --end-time $(date +%Y-%m-%dT%H:%M:%S) \
    --period 86400 \
    --statistics Average \
    --output json 2>/dev/null | jq -r '.Datapoints[].Average' | awk '{sum+=$1} END {printf "%.1f", sum/NR}' || echo "N/A")
  
  # Generate recommendation
  if [[ "$cpu_avg" != "N/A" ]]; then
    if (( $(echo "$cpu_avg < $CPU_THRESHOLD_LOW" | bc -l) )); then
      recommendation="DOWNSIZE"
      suggested_type="t3.medium"  # Example suggestion
    elif (( $(echo "$cpu_avg > $CPU_THRESHOLD_HIGH" | bc -l) )); then
      recommendation="UPSIZE"
      suggested_type="m5.large"  # Example suggestion
    else
      recommendation="OPTIMAL"
      suggested_type="$current_type"
    fi
  else
    recommendation="INSUFFICIENT_DATA"
    suggested_type="$current_type"
  fi
  
  echo "$instance_id | $current_type | CPU: ${cpu_avg}% | Mem: ${memory_avg}% | Recommendation: $recommendation (→ $suggested_type)"
done

Python Right-Sizing Engine

# ✅ GOOD — Python right-sizing engine with historical analysis
import boto3
from datetime import datetime, timedelta
from typing import Dict, List, Tuple
import statistics

class RightSizingAnalyzer:
    """Analyzes EC2 instances for right-sizing opportunities."""
    
    def __init__(self, region: str = "us-east-1"):
        self.ec2 = boto3.client('ec2', region_name=region)
        self.cloudwatch = boto3.client('cloudwatch', region_name=region)
        self.ssm = boto3.client('ssm', region_name=region)
        
        # Instance type hierarchy for right-sizing decisions
        self.instance_hierarchy = {
            't2': ['t3', 't4g'],
            't3': ['t2', 't4g'],
            'm5': ['m4', 'm6g'],
            'c5': ['c4', 'c6g'],
            'r5': ['r4', 'r6g'],
        }
        
        self.thresholds = {
            'cpu_low': 30,
            'cpu_high': 80,
            'memory_low': 40,
            'memory_high': 85,
            'days': 14,
        }
    
    def get_instance_metrics(self, instance_id: str, days: int = 14) -> Dict[str, float]:
        """Get CPU and memory metrics for an instance."""
        end_time = datetime.utcnow()
        start_time = end_time - timedelta(days=days)
        
        # Get CPU utilization
        cpu_stats = self.cloudwatch.get_metric_statistics(
            Namespace='AWS/EC2',
            MetricName='CPUUtilization',
            Dimensions=[{'Name': 'InstanceId', 'Value': instance_id}],
            StartTime=start_time,
            EndTime=end_time,
            Period=86400,
            Statistics=['Average'],
            Unit='Percent'
        )
        
        cpu_values = [dp['Average'] for dp in cpu_stats.get('Datapoints', [])]
        cpu_avg = statistics.mean(cpu_values) if cpu_values else None
        
        # Get memory utilization (requires CloudWatch Agent)
        try:
            memory_stats = self.cloudwatch.get_metric_statistics(
                Namespace='CWAgent',
                MetricName='memory_utilization',
                Dimensions=[
                    {'Name': 'InstanceId', 'Value': instance_id},
                    {'Name': 'InstanceType', 'Value': 'ec2'}
                ],
                StartTime=start_time,
                EndTime=end_time,
                Period=86400,
                Statistics=['Average'],
                Unit='Percent'
            )
            memory_values = [dp['Average'] for dp in memory_stats.get('Datapoints', [])]
            memory_avg = statistics.mean(memory_values) if memory_values else None
        except Exception:
            memory_avg = None
        
        return {
            'cpu_avg': round(cpu_avg, 2) if cpu_avg else None,
            'memory_avg': round(memory_avg, 2) if memory_avg else None,
            'cpu_data_points': len(cpu_values),
            'memory_data_points': len(memory_values) if memory_avg else 0,
        }
    
    def suggest_right_size(self, instance_type: str, metrics: Dict[str, float]) -> Tuple[str, str]:
        """Suggest a right-sized instance type based on metrics."""
        cpu = metrics.get('cpu_avg')
        memory = metrics.get('memory_avg')
        
        # If insufficient data, return original type
        if not cpu and not memory:
            return instance_type, "INSUFFICIENT_DATA"
        
        # If high CPU, consider up-sizing
        if cpu and cpu > self.thresholds['cpu_high']:
            return self._upsize(instance_type), "HIGH_CPU"
        
        # If low CPU, consider down-sizing
        if cpu and cpu < self.thresholds['cpu_low']:
            return self._downsize(instance_type), "LOW_CPU"
        
        # If high memory, consider memory-optimized
        if memory and memory > self.thresholds['memory_high']:
            return self._memory_optimize(instance_type), "HIGH_MEMORY"
        
        # If low memory, consider general-purpose
        if memory and memory < self.thresholds['memory_low']:
            return self._general_purpose(instance_type), "LOW_MEMORY"
        
        return instance_type, "OPTIMAL"
    
    def _downsize(self, instance_type: str) -> str:
        """Downsize instance type if possible."""
        base_type = next((k for k in self.instance_hierarchy.keys() if instance_type.startswith(k)), None)
        if base_type:
            smaller_types = self.instance_hierarchy[base_type]
            if smaller_types:
                return f"{smaller_types[0]}.large"
        return instance_type
    
    def _upsize(self, instance_type: str) -> str:
        """Upsize instance type if needed."""
        base_type = next((k for k in self.instance_hierarchy.keys() if instance_type.startswith(k)), None)
        if base_type:
            larger_types = [t for t in self.instance_hierarchy.get(base_type, []) if t != instance_type]
            if larger_types:
                return f"{larger_types[0]}.xlarge"
        return instance_type
    
    def _memory_optimize(self, instance_type: str) -> str:
        """Suggest memory-optimized instance type."""
        if instance_type.startswith('t'):
            return 'r5.large'
        elif instance_type.startswith('m'):
            return 'r5.xlarge'
        return f"r{instance_type[1:]}" if instance_type[1] != 'r' else instance_type
    
    def _general_purpose(self, instance_type: str) -> str:
        """Suggest general-purpose instance type."""
        if instance_type.startswith('r'):
            return 'm5.large'
        elif instance_type.startswith('c'):
            return 't3.large'
        return f"m{instance_type[1:]}" if instance_type[1] != 'm' else instance_type
    
    def analyze_instance(self, instance_id: str) -> Dict:
        """Analyze a single instance for right-sizing."""
        # Get instance details
        response = self.ec2.describe_instances(InstanceIds=[instance_id])
        instance = response['Reservations'][0]['Instances'][0]
        instance_type = instance['InstanceType']
        
        # Get metrics
        metrics = self.get_instance_metrics(instance_id, self.thresholds['days'])
        
        # Suggest right size
        suggested_type, reason = self.suggest_right_size(instance_type, metrics)
        
        return {
            'instance_id': instance_id,
            'current_type': instance_type,
            'suggested_type': suggested_type,
            'reason': reason,
            'metrics': metrics,
            'potential_savings': self._estimate_savings(instance_type, suggested_type),
        }
    
    def _estimate_savings(self, current_type: str, suggested_type: str) -> float:
        """Estimate potential monthly savings from right-sizing."""
        # Simplified pricing model (replace with actual pricing data)
        pricing = {
            't3.large': 0.0832,
            't3.xlarge': 0.1664,
            't3.2xlarge': 0.3328,
            'm5.large': 0.096,
            'm5.xlarge': 0.192,
            'm5.2xlarge': 0.384,
            'r5.large': 0.126,
            'r5.xlarge': 0.252,
            'r5.2xlarge': 0.504,
        }
        
        current_price = pricing.get(current_type, 0.1)
        suggested_price = pricing.get(suggested_type, 0.1)
        
        monthly_usage_hours = 730  # Average hours per month
        monthly_savings = (current_price - suggested_price) * monthly_usage_hours
        
        return round(max(0, monthly_savings), 2)
    
    def analyze_all_instances(self) -> List[Dict]:
        """Analyze all instances in the region."""
        instances = self.ec2.describe_instances(
            Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]
        )
        
        results = []
        for reservation in instances['Reservations']:
            for instance in reservation['Instances']:
                result = self.analyze_instance(instance['InstanceId'])
                results.append(result)
        
        return results

# Usage example
if __name__ == "__main__":
    analyzer = RightSizingAnalyzer(region="us-east-1")
    results = analyzer.analyze_all_instances()
    
    print("Right-Sizing Analysis Results:")
    print("-" * 80)
    
    total_monthly_savings = 0
    for result in results:
        if result['reason'] != 'OPTIMAL':
            print(f"Instance: {result['instance_id']}")
            print(f"  Current: {result['current_type']}")
            print(f"  Suggested: {result['suggested_type']} ({result['reason']})")
            print(f"  Monthly Savings: ${result['potential_savings']}")
            print()
            total_monthly_savings += result['potential_savings']
    
    print(f"Total Potential Monthly Savings: ${total_monthly_savings:.2f}")

Pattern 5: Spot Instance Strategy

Spot instance optimization reduces compute costs by up to 90% for fault-tolerant workloads.

BAD — Simple spot request without termination handling

# ❌ BAD — No termination handling, no replacement strategy
aws ec2 request-spot-instances \
  --spot-price "0.05" \
  --instance-count 1 \
  --type "one-time" \
  --launch-specification file://launch-spec.json

GOOD — Comprehensive spot instance management script

#!/bin/bash
# ✅ GOOD — Spot instance with termination handling, replacement strategy, and scaling
set -euo pipefail

SPOT_PRICE="${SPOT_PRICE:-0.05}"
INSTANCE_TYPE="${INSTANCE_TYPE:-c5.large}"
REGION="${AWS_REGION:-us-east-1}"
MIN_INSTANCES="${MIN_INSTANCES:-2}"
MAX_INSTANCES="${MAX_INSTANCES:-10}"

# Spot request with replacement strategy
create_spot_fleet() {
  local fleet_config=$(cat <<EOF
{
  "IamFleetRole": "arn:aws:iam::123456789012:role/spot-fleet-role",
  "TargetCapacity": $MIN_INSTANCES,
  "SpotPrice": "$SPOT_PRICE",
  "AllocationStrategy": "lowestPrice",
  "LaunchSpecifications": [
    {
      "ImageId": "ami-0123456789abcdef0",
      "InstanceType": "$INSTANCE_TYPE",
      "KeyName": "my-key",
      "SubnetId": "subnet-0123456789abcdef0",
      "IamInstanceProfile": {
        "Arn": "arn:aws:iam::123456789012:instance-profile/spot-instance-profile"
      },
      "SpotPrice": "$SPOT_PRICE"
    }
  ],
  "TerminateInstancesWithExpiration": true,
  "ReplaceUnhealthyInstances": true
}
EOF
)
  
  aws ec2 request-spot-fleet \
    --spot-fleet-request-data "$fleet_config" \
    --region "$REGION"
}

# Check spot instance health
check_spot_health() {
  local fleet_id="$1"
  
  # Get spot instance requests
  aws ec2 describe-spot-instance-requests \
    --filters "Name=spot-fleet-request-id,Values=$fleet_id" \
    --query 'SpotInstanceRequests[].{InstanceId:InstanceId,State:State,Status:Status}' \
    --output table
  
  # Check for terminations
  aws ec2 describe-spot-instance-requests \
    --filters "Name=spot-fleet-request-id,Values=$fleet_id" \
    --query 'SpotInstanceRequests[?State==`closed`]' \
    --output text
}

# Scale spot fleet based on demand
scale_spot_fleet() {
  local fleet_id="$1"
  local new_capacity="$2"
  
  aws ec2 modify-spot-fleet-request \
    --spot-fleet-request-id "$fleet_id" \
    --target-capacity "$new_capacity" \
    --terminate-instances-with-expiration
}

# Main execution
case "${1:-create}" in
  create)
    echo "Creating spot fleet with $MIN_INSTANCES instances at $SPOT_PRICE"
    create_spot_fleet
    ;;
  check)
    check_spot_health "$2"
    ;;
  scale)
    scale_spot_fleet "$2" "$3"
    ;;
  *)
    echo "Usage: $0 {create|check|scale}"
    exit 1
    ;;
esac

Python Spot Instance Optimizer

# ✅ GOOD — Python spot instance optimizer with termination handling
import boto3
from datetime import datetime, timedelta
from typing import Dict, List, Optional
import statistics
import time

class SpotInstanceOptimizer:
    """Optimizes spot instance usage for cost savings."""
    
    def __init__(self, region: str = "us-east-1"):
        self.ec2 = boto3.client('ec2', region_name=region)
        self.cloudwatch = boto3.client('cloudwatch', region_name=region)
        
        self.spot_pricing_history = {}
        self.recommendation_cache = {}
    
    def get_spot_price_history(self, instance_types: List[str], days: int = 7) -> Dict[str, List[float]]:
        """Get historical spot prices for given instance types."""
        end_time = datetime.utcnow()
        start_time = end_time - timedelta(days=days)
        
        prices = {}
        
        for instance_type in instance_types:
            try:
                response = self.ec2.describe_spot_price_history(
                    InstanceTypes=[instance_type],
                    StartTime=start_time,
                    EndTime=end_time,
                    MaxResults=1000
                )
                
                price_list = [float(dp['SpotPrice']) for dp in response['SpotPriceHistory']]
                prices[instance_type] = price_list
                
                # Cache the data
                self.spot_pricing_history[instance_type] = {
                    'prices': price_list,
                    'avg': statistics.mean(price_list) if price_list else 0,
                    'min': min(price_list) if price_list else 0,
                    'max': max(price_list) if price_list else 0,
                    'std': statistics.stdev(price_list) if len(price_list) > 1 else 0,
                }
            except Exception as e:
                print(f"Error fetching spot price history for {instance_type}: {e}")
        
        return prices
    
    def recommend_spot_instance(self, instance_type: str, current_on_demand_price: float) -> Dict:
        """Recommend whether to use spot for given instance type."""
        history = self.spot_pricing_history.get(instance_type, {})
        
        if not history:
            return {
                'instance_type': instance_type,
                'recommendation': 'UNKNOWN',
                'reason': 'Insufficient historical data',
            }
        
        avg_price = history['avg']
        min_price = history['min']
        max_price = history['max']
        std = history['std']
        
        # Calculate savings
        savings_percentage = ((current_on_demand_price - avg_price) / current_on_demand_price) * 100
        
        # Determine recommendation
        if savings_percentage > 50 and std < 0.05:
            recommendation = 'STRONG_RECOMMENDATION'
            reason = f'High savings ({savings_percentage:.1f}%) with low volatility'
        elif savings_percentage > 30:
            recommendation = 'RECOMMENDATION'
            reason = f'Moderate savings ({savings_percentage:.1f}%)'
        elif savings_percentage > 10:
            recommendation = 'CONSIDER'
            reason = f'Some savings ({savings_percentage:.1f}%), monitor volatility'
        else:
            recommendation = 'NOT_RECOMMENDED'
            reason = f'Low savings ({savings_percentage:.1f}%)'
        
        return {
            'instance_type': instance_type,
            'recommendation': recommendation,
            'reason': reason,
            'spot_avg_price': round(avg_price, 4),
            'spot_min_price': round(min_price, 4),
            'spot_max_price': round(max_price, 4),
            'on_demand_price': current_on_demand_price,
            'savings_percentage': round(savings_percentage, 1),
            'price_volatility': round(std, 4),
        }
    
    def check_spot_capacity(self, instance_types: List[str], availability_zone: str) -> Dict[str, bool]:
        """Check spot capacity availability."""
        capacity = {}
        
        for instance_type in instance_types:
            try:
                response = self.ec2.describe_spot_instance_requests(
                    InstanceTypes=[instance_type],
                    AvailabilityZone=availability_zone,
                    MaxResults=1
                )
                capacity[instance_type] = True
            except Exception:
                capacity[instance_type] = False
        
        return capacity
    
    def estimate_savings(self, instance_type: str, hours_per_month: int = 730) -> Dict:
        """Estimate monthly savings from spot instances."""
        history = self.spot_pricing_history.get(instance_type, {})
        
        if not history:
            return {'error': 'No historical data available'}
        
        avg_spot_price = history['avg']
        
        # Get on-demand price (simplified - use actual pricing API in production)
        on_demand_prices = {
            'c5.large': 0.17,
            'c5.xlarge': 0.34,
            'c5.2xlarge': 0.68,
            'm5.large': 0.096,
            'm5.xlarge': 0.192,
            'r5.large': 0.126,
            'r5.xlarge': 0.252,
        }
        
        on_demand_price = on_demand_prices.get(instance_type, avg_spot_price * 2)
        
        on_demand_cost = on_demand_price * hours_per_month
        spot_cost = avg_spot_price * hours_per_month
        savings = on_demand_cost - spot_cost
        savings_percentage = (savings / on_demand_cost) * 100
        
        return {
            'instance_type': instance_type,
            'on_demand_cost': round(on_demand_cost, 2),
            'spot_cost': round(spot_cost, 2),
            'monthly_savings': round(savings, 2),
            'savings_percentage': round(savings_percentage, 1),
            'break_even_price': round(spot_cost / hours_per_month, 4),
        }
    
    def get_all_recommendations(self) -> List[Dict]:
        """Get recommendations for all common instance types."""
        instance_types = ['c5.large', 'c5.xlarge', 'c5.2xlarge', 'm5.large', 'm5.xlarge', 'r5.large', 'r5.xlarge']
        on_demand_prices = {
            'c5.large': 0.17, 'c5.xlarge': 0.34, 'c5.2xlarge': 0.68,
            'm5.large': 0.096, 'm5.xlarge': 0.192,
            'r5.large': 0.126, 'r5.xlarge': 0.252,
        }
        
        self.get_spot_price_history(instance_types)
        
        recommendations = []
        for instance_type in instance_types:
            recommendation = self.recommend_spot_instance(
                instance_type, 
                on_demand_prices.get(instance_type, 0)
            )
            savings = self.estimate_savings(instance_type)
            recommendation.update(savings)
            recommendations.append(recommendation)
        
        return recommendations

# Usage example
if __name__ == "__main__":
    optimizer = SpotInstanceOptimizer(region="us-east-1")
    recommendations = optimizer.get_all_recommendations()
    
    print("Spot Instance Optimization Recommendations")
    print("=" * 80)
    
    total_monthly_savings = 0
    
    for rec in recommendations:
        if rec['recommendation'] in ['STRONG_RECOMMENDATION', 'RECOMMENDATION']:
            print(f"\nInstance: {rec['instance_type']}")
            print(f"  Recommendation: {rec['recommendation']}")
            print(f"  Reason: {rec['reason']}")
            print(f"  On-demand: ${rec['on_demand_price']}/hr")
            print(f"  Spot avg: ${rec['spot_avg_price']}/hr")
            print(f"  Monthly Savings: ${rec['monthly_savings']}")
            
            total_monthly_savings += rec['monthly_savings']
    
    print(f"\n" + "=" * 80)
    print(f"Total Potential Monthly Savings: ${total_monthly_savings:.2f}")

Pattern 6: Reserved Instance Optimization

Reserved instance optimization analyzes usage patterns to recommend RI purchases.

BAD — Manual analysis without historical data

# ❌ BAD — No historical analysis, no ROI calculation
# Just buying RIs without data-driven decisions
aws ec2 purchase-reserved-instances-offering \
  --reserved-instances-offering-id "ri-offering-123" \
  --instance-count 5

GOOD — Data-driven RI optimization script

#!/bin/bash
# ✅ GOOD — Historical analysis with ROI calculation
set -euo pipefail

REGION="${AWS_REGION:-us-east-1}"
ANALYSIS_DAYS="${ANALYSIS_DAYS:-90}"

# Get historical instance usage
get_instance_usage() {
  local instance_type="$1"
  
  # Get average CPU utilization over analysis period
  aws cloudwatch get-metric-statistics \
    --metric-name CPUUtilization \
    --dimensions Name=InstanceId,Value=unknown \
    --namespace AWS/EC2 \
    --start-time $(date -d "$ANALYSIS_DAYS days ago" +%Y-%m-%dT%H:%M:%S) \
    --end-time $(date +%Y-%m-%dT%H:%M:%S) \
    --period 86400 \
    --statistics Average \
    --query 'Datapoints[].Average' \
    --output text | awk '{sum+=$1; count++} END {printf "%.1f", sum/count}'
}

# Calculate RI ROI
calculate_ri_roi() {
  local on_demand_hourly="$1"
  local ri_upfront="$2"
  local ri_annual="$3"
  local usage_hours="$4"
  
  # Calculate total cost with on-demand
  local on_demand_total=$(echo "$on_demand_hourly * $usage_hours" | bc -l)
  
  # Calculate total cost with RI (upfront + annual)
  local ri_total=$(echo "$ri_upfront + $ri_annual" | bc -l)
  
  # Calculate savings
  local savings=$(echo "$on_demand_total - $ri_total" | bc -l)
  local savings_percentage=$(echo "($savings / $on_demand_total) * 100" | bc -l)
  
  echo "On-Demand Total: \$on_demand_total"
  echo "RI Total: \$ri_total"
  echo "Savings: \$savings ($savings_percentage%)"
}

# Analyze instance usage and recommend RIs
analyze_ri_opportunity() {
  local instance_type="$1"
  local current_count="$2"
  
  echo "=== Reserved Instance Analysis ==="
  echo "Instance Type: $instance_type"
  echo "Current Count: $current_count"
  echo "Analysis Period: $ANALYSIS_DAYS days"
  echo ""
  
  # Get on-demand pricing
  local on_demand_price=$(aws ec2 describe-spot-price-history \
    --instance-types "$instance_type" \
    --product-description "Linux/UNIX" \
    --query 'SpotPriceHistory[0].SpotPrice' \
    --output text)
  
  # Get RI pricing (simplified - use actual RI pricing API)
  local ri_pricing={
    "c5.large": {"upfront": 450, "annual": 600, "hourly": 0.17},
    "c5.xlarge": {"upfront": 900, "annual": 1200, "hourly": 0.34},
    "m5.large": {"upfront": 300, "annual": 400, "hourly": 0.096},
    "m5.xlarge": {"upfront": 600, "annual": 800, "hourly": 0.192},
  }
  
  if [[ -v ri_pricing["$instance_type"] ]]; then
    local upfront="${ri_pricing[$instance_type, upfront]}"
    local annual="${ri_pricing[$instance_type, annual]}"
    local hourly="${ri_pricing[$instance_type, hourly]}"
    
    # Assume 24/7 usage
    local usage_hours=$((ANALYSIS_DAYS * 24))
    
    echo "Pricing:"
    echo "  On-Demand: \${hourly}/hour"
    echo "  RI Upfront: \${upfront}"
    echo "  RI Annual: \${annual}"
    echo ""
    
    echo "Projected Usage: $usage_hours hours"
    echo ""
    
    calculate_ri_roi "$hourly" "$upfront" "$annual" "$usage_hours"
  else
    echo "RI pricing not available for $instance_type"
  fi
}

# Main execution
instance_type="${1:-c5.large}"
count="${2:-5}"

analyze_ri_opportunity "$instance_type" "$count"

Python RI Optimizer

# ✅ GOOD — Python RI optimizer with ROI calculations
import boto3
from datetime import datetime, timedelta
from typing import Dict, List, Optional
from dataclasses import dataclass
import statistics

@dataclass
class InstanceUsage:
    instance_id: str
    instance_type: str
    avg_cpu: float
    hours_used: int
    days_used: int

@dataclass
class RIRecommendation:
    instance_type: str
    recommended_count: int
    upfront_cost: float
    annual_cost: float
    on_demand_cost: float
    roi_percentage: float
    break_even_months: float
    recommendation: str

class ReservedInstanceOptimizer:
    """Optimizes reserved instance purchases for cost savings."""
    
    def __init__(self, region: str = "us-east-1"):
        self.ec2 = boto3.client('ec2', region_name=region)
        self.cloudwatch = boto3.client('cloudwatch', region_name=region)
        self.pricing = boto3.client('pricing', region_name='us-east-1')
        
        # Simplified RI pricing (replace with actual AWS Pricing API in production)
        self.ri_pricing = {
            'c5.large': {'upfront': 450, 'annual': 600, 'hourly': 0.17},
            'c5.xlarge': {'upfront': 900, 'annual': 1200, 'hourly': 0.34},
            'c5.2xlarge': {'upfront': 1800, 'annual': 2400, 'hourly': 0.68},
            'm5.large': {'upfront': 300, 'annual': 400, 'hourly': 0.096},
            'm5.xlarge': {'upfront': 600, 'annual': 800, 'hourly': 0.192},
            'm5.2xlarge': {'upfront': 1200, 'annual': 1600, 'hourly': 0.384},
            'r5.large': {'upfront': 400, 'annual': 550, 'hourly': 0.126},
            'r5.xlarge': {'upfront': 800, 'annual': 1100, 'hourly': 0.252},
        }
        
        self.usage_analysis = {}
    
    def get_instance_usage(self, instance_id: str, days: int = 90) -> Optional[InstanceUsage]:
        """Get historical usage data for an instance."""
        end_time = datetime.utcnow()
        start_time = end_time - timedelta(days=days)
        
        try:
            # Get CPU utilization data
            response = self.cloudwatch.get_metric_statistics(
                Namespace='AWS/EC2',
                MetricName='CPUUtilization',
                Dimensions=[{'Name': 'InstanceId', 'Value': instance_id}],
                StartTime=start_time,
                EndTime=end_time,
                Period=86400,
                Statistics=['Average'],
                Unit='Percent'
            )
            
            datapoints = response.get('Datapoints', [])
            if not datapoints:
                return None
            
            avg_cpu = statistics.mean([dp['Average'] for dp in datapoints])
            
            # Calculate hours used (assume running 24/7)
            hours_used = days * 24
            
            return InstanceUsage(
                instance_id=instance_id,
                instance_type='UNKNOWN',  # Get this from describe_instances
                avg_cpu=round(avg_cpu, 2),
                hours_used=hours_used,
                days_used=days,
            )
        except Exception as e:
            print(f"Error getting usage for {instance_id}: {e}")
            return None
    
    def analyze_all_instances(self, days: int = 90) -> List[InstanceUsage]:
        """Analyze usage for all running instances."""
        # Get all running instances
        response = self.ec2.describe_instances(
            Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]
        )
        
        usages = []
        for reservation in response['Reservations']:
            for instance in reservation['Instances']:
                instance_type = instance['InstanceType']
                instance_id = instance['InstanceId']
                
                usage = self.get_instance_usage(instance_id, days)
                if usage:
                    usage.instance_type = instance_type
                    usages.append(usage)
                
                # Add instance type to analysis
                if instance_type not in self.usage_analysis:
                    self.usage_analysis[instance_type] = {
                        'count': 0,
                        'total_hours': 0,
                        'avg_cpu': [],
                    }
                
                self.usage_analysis[instance_type]['count'] += 1
                self.usage_analysis[instance_type]['total_hours'] += usage.hours_used
                self.usage_analysis[instance_type]['avg_cpu'].append(usage.avg_cpu)
        
        return usages
    
    def calculate_ri_roi(self, instance_type: str, count: int, days: int = 365) -> RIRecommendation:
        """Calculate ROI for reserved instances."""
        pricing = self.ri_pricing.get(instance_type)
        if not pricing:
            return RIRecommendation(
                instance_type=instance_type,
                recommended_count=count,
                upfront_cost=0,
                annual_cost=0,
                on_demand_cost=0,
                roi_percentage=0,
                break_even_months=0,
                recommendation='NO_DATA',
            )
        
        hourly_price = pricing['hourly']
        upfront = pricing['upfront'] * count
        annual = pricing['annual'] * count
        
        # Calculate on-demand cost for the period
        usage = self.usage_analysis.get(instance_type, {})
        total_hours = usage.get('total_hours', days * 24 * count)
        
        on_demand_cost = hourly_price * total_hours
        
        # Calculate savings
        ri_total = upfront + annual
        savings = on_demand_cost - ri_total
        roi_percentage = (savings / on_demand_cost) * 100 if on_demand_cost > 0 else 0
        
        # Calculate break-even point
        monthly_ri_cost = annual / 12
        monthly_on_demand_cost = hourly_price * (days * 24 * count) / 12
        break_even_months = upfront / (monthly_on_demand_cost - monthly_ri_cost) if (monthly_on_demand_cost - monthly_ri_cost) > 0 else float('inf')
        
        # Determine recommendation
        if roi_percentage > 30:
            recommendation = 'STRONG_RECOMMENDATION'
        elif roi_percentage > 15:
            recommendation = 'RECOMMENDATION'
        elif roi_percentage > 5:
            recommendation = 'CONSIDER'
        else:
            recommendation = 'NOT_RECOMMENDED'
        
        return RIRecommendation(
            instance_type=instance_type,
            recommended_count=count,
            upfront_cost=upfront,
            annual_cost=annual,
            on_demand_cost=round(on_demand_cost, 2),
            roi_percentage=round(roi_percentage, 2),
            break_even_months=round(break_even_months, 1),
            recommendation=recommendation,
        )
    
    def get_all_recommendations(self, days: int = 365) -> List[RIRecommendation]:
        """Get RI recommendations for all instance types."""
        self.analyze_all_instances(days=days)
        
        recommendations = []
        for instance_type, analysis in self.usage_analysis.items():
            count = analysis['count']
            recommendation = self.calculate_ri_roi(instance_type, count, days)
            recommendations.append(recommendation)
        
        return recommendations
    
    def generate_ri_report(self, days: int = 365) -> str:
        """Generate a comprehensive RI optimization report."""
        recommendations = self.get_all_recommendations(days)
        
        report = ["=" * 80, "Reserved Instance Optimization Report", "=" * 80, ""]
        
        total_annual_savings = 0
        total_upfront_investment = 0
        
        for rec in recommendations:
            if rec.recommendation in ['STRONG_RECOMMENDATION', 'RECOMMENDATION']:
                report.append(f"Instance Type: {rec.instance_type}")
                report.append(f"  Recommended Count: {rec.recommended_count}")
                report.append(f"  Recommendation: {rec.recommendation}")
                report.append(f"  Upfront Cost: ${rec.upfront_cost:,.2f}")
                report.append(f"  Annual Cost: ${rec.annual_cost:,.2f}")
                report.append(f"  On-Demand Cost: ${rec.on_demand_cost:,.2f}")
                report.append(f"  ROI: {rec.roi_percentage:.1f}%")
                report.append(f"  Break-Even: {rec.break_even_months:.1f} months")
                report.append("")
                
                total_annual_savings += rec.on_demand_cost - rec.annual_cost - rec.upfront_cost
                total_upfront_investment += rec.upfront_cost
        
        report.append("=" * 80)
        report.append(f"Total Upfront Investment: ${total_upfront_investment:,.2f}")
        report.append(f"Total Annual Savings: ${total_annual_savings:,.2f}")
        report.append("=" * 80)
        
        return "\n".join(report)

# Usage example
if __name__ == "__main__":
    optimizer = ReservedInstanceOptimizer(region="us-east-1")
    report = optimizer.generate_ri_report(days=365)
    print(report)

Pattern 7: Cost Allocation Tagging

Cost allocation tagging implements chargeback/showback models through proper resource tagging.

BAD — Manual tagging without validation

# ❌ BAD — No validation, inconsistent tags
aws ec2 create-tags \
  --resources i-1234567890abcdef0 \
  --tags Key=Project,Value=MyProject Key=Environment,Value=prod

GOOD — Automated tagging with validation and enforcement

#!/bin/bash
# ✅ GOOD — Automated tagging with validation and cost allocation
set -euo pipefail

# Cost allocation tags (required for all resources)
REQUIRED_TAGS=(
  "Project"
  "Environment"
  "Owner"
  "CostCenter"
  "Department"
)

# Validate tags
validate_tags() {
  local tags="$1"
  
  for tag in "${REQUIRED_TAGS[@]}"; do
    if ! echo "$tags" | grep -q "\"Key\":\"$tag\""; then
      echo "ERROR: Missing required tag: $tag"
      return 1
    fi
  done
  
  echo "All required tags present"
  return 0
}

# Tag EC2 instance
tag_ec2_instance() {
  local instance_id="$1"
  local tags="$2"
  
  echo "Tagging EC2 instance: $instance_id"
  
  if validate_tags "$tags"; then
    aws ec2 create-tags \
      --resources "$instance_id" \
      --tags "$tags" \
      --region "${AWS_REGION:-us-east-1}"
    
    echo "Tags applied successfully"
  else
    echo "Tagging failed: validation error"
    return 1
  fi
}

# Tag S3 bucket
tag_s3_bucket() {
  local bucket_name="$1"
  local tags="$2"
  
  echo "Tagging S3 bucket: $bucket_name"
  
  if validate_tags "$tags"; then
    aws s3api put-bucket-tagging \
      --bucket "$bucket_name" \
      --tagging "$tags"
    
    echo "Tags applied successfully"
  else
    echo "Tagging failed: validation error"
    return 1
  fi
}

# Tag RDS instance
tag_rds_instance() {
  local db_instance_identifier="$1"
  local tags="$2"
  
  echo "Tagging RDS instance: $db_instance_identifier"
  
  if validate_tags "$tags"; then
    aws rds add-tags-to-resource \
      --resource-name "arn:aws:rds:${AWS_REGION:-us-east-1}:123456789012:db:$db_instance_identifier" \
      --tags "$tags"
    
    echo "Tags applied successfully"
  else
    echo "Tagging failed: validation error"
    return 1
  fi
}

# Example usage
INSTANCE_ID="${1:-i-1234567890abcdef0}"
TAGS='[
  {"Key":"Project","Value":"WebApplication"},
  {"Key":"Environment","Value":"production"},
  {"Key":"Owner","Value":"john.doe@company.com"},
  {"Key":"CostCenter","Value":"CC12345"},
  {"Key":"Department","Value":"Engineering"}
]'

tag_ec2_instance "$INSTANCE_ID" "$TAGS"

Python Tagging Manager

# ✅ GOOD — Python tagging manager with cost allocation enforcement
import boto3
from typing import Dict, List, Optional
from datetime import datetime
import re

class CostAllocationTagManager:
    """Manages cost allocation tagging across AWS resources."""
    
    # Required cost allocation tags
    REQUIRED_TAGS = {
        'Project': {'type': 'string', 'pattern': r'^[a-zA-Z0-9-_.]{1,50}#x27;},
        'Environment': {'type': 'string', 'values': ['dev', 'staging', 'production', 'testing']},
        'Owner': {'type': 'email', 'pattern': r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}#x27;},
        'CostCenter': {'type': 'string', 'pattern': r'^[A-Z]{2}\d{5}#x27;},
        'Department': {'type': 'string', 'values': ['Engineering', 'Marketing', 'Sales', 'Finance', 'Operations']},
        'Application': {'type': 'string', 'pattern': r'^[a-zA-Z0-9-_.]{1,50}#x27;},
        'BusinessUnit': {'type': 'string', 'pattern': r'^[a-zA-Z0-9-_.]{1,50}#x27;},
    }
    
    def __init__(self, region: str = "us-east-1"):
        self.ec2 = boto3.client('ec2', region_name=region)
        self.s3 = boto3.client('s3', region_name=region)
        self.rds = boto3.client('rds', region_name=region)
        self.iam = boto3.client('iam', region_name=region)
        
        self.tag_cache: Dict[str, Dict[str, str]] = {}
    
    def validate_tag(self, key: str, value: str) -> tuple:
        """Validate a tag key-value pair."""
        if key not in self.REQUIRED_TAGS:
            return True, None  # Optional tag
        
        tag_spec = self.REQUIRED_TAGS[key]
        
        # Check if value is in allowed values
        if 'values' in tag_spec and value not in tag_spec['values']:
            return False, f"Value '{value}' not in allowed values: {tag_spec['values']}"
        
        # Check regex pattern
        if 'pattern' in tag_spec:
            pattern = tag_spec['pattern']
            if tag_spec.get('type') == 'email':
                pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}#x27;
            
            if not re.match(pattern, value):
                return False, f"Value '{value}' does not match pattern: {pattern}"
        
        return True, None
    
    def validate_tags(self, tags: List[Dict[str, str]]) -> tuple:
        """Validate all tags and ensure required tags are present."""
        tag_dict = {tag['Key']: tag['Value'] for tag in tags}
        
        # Check required tags
        for required_tag in self.REQUIRED_TAGS:
            if required_tag not in tag_dict:
                return False, f"Missing required tag: {required_tag}"
        
        # Validate each tag
        for key, value in tag_dict.items():
            valid, error = self.validate_tag(key, value)
            if not valid:
                return False, f"Invalid tag {key}: {error}"
        
        return True, None
    
    def tag_ec2_instance(self, instance_id: str, tags: List[Dict[str, str]]) -> bool:
        """Tag an EC2 instance with cost allocation tags."""
        # Validate tags
        valid, error = self.validate_tags(tags)
        if not valid:
            print(f"Tag validation failed: {error}")
            return False
        
        try:
            self.ec2.create_tags(
                Resources=[instance_id],
                Tags=tags
            )
            self.tag_cache[instance_id] = {tag['Key']: tag['Value'] for tag in tags}
            print(f"Successfully tagged EC2 instance {instance_id}")
            return True
        except Exception as e:
            print(f"Error tagging EC2 instance: {e}")
            return False
    
    def tag_s3_bucket(self, bucket_name: str, tags: List[Dict[str, str]]) -> bool:
        """Tag an S3 bucket with cost allocation tags."""
        valid, error = self.validate_tags(tags)
        if not valid:
            print(f"Tag validation failed: {error}")
            return False
        
        try:
            self.s3.put_bucket_tagging(
                Bucket=bucket_name,
                Tagging={'TagSet': tags}
            )
            self.tag_cache[bucket_name] = {tag['Key']: tag['Value'] for tag in tags}
            print(f"Successfully tagged S3 bucket {bucket_name}")
            return True
        except Exception as e:
            print(f"Error tagging S3 bucket: {e}")
            return False
    
    def tag_rds_instance(self, db_instance_id: str, tags: List[Dict[str, str]]) -> bool:
        """Tag an RDS instance with cost allocation tags."""
        valid, error = self.validate_tags(tags)
        if not valid:
            print(f"Tag validation failed: {error}")
            return False
        
        try:
            response = self.rds.describe_db_instances(DBInstanceIdentifier=db_instance_id)
            arn = response['DBInstances'][0]['DBInstanceArn']
            
            self.rds.add_tags_to_resource(
                ResourceName=arn,
                Tags=tags
            )
            self.tag_cache[db_instance_id] = {tag['Key']: tag['Value'] for tag in tags}
            print(f"Successfully tagged RDS instance {db_instance_id}")
            return True
        except Exception as e:
            print(f"Error tagging RDS instance: {e}")
            return False
    
    def get_resource_tags(self, resource_id: str) -> Dict[str, str]:
        """Get tags for a resource."""
        if resource_id in self.tag_cache:
            return self.tag_cache[resource_id]
        
        try:
            response = self.ec2.describe_tags(
                Filters=[{'Name': 'resource-id', 'Values': [resource_id]}]
            )
            tags = {tag['Key']: tag['Value'] for tag in response.get('Tags', [])}
            self.tag_cache[resource_id] = tags
            return tags
        except Exception:
            return {}
    
    def generate_cost_allocation_report(self) -> Dict[str, float]:
        """Generate cost allocation report by tag."""
        # This would integrate with AWS Cost Explorer in production
        # For demo, we'll simulate the report structure
        
        report = {
            'tags_analyzed': len(self.tag_cache),
            'cost_by_project': {},
            'cost_by_environment': {},
            'cost_by_owner': {},
        }
        
        # In production, query AWS Cost Explorer with tag dimensions
        # Example query structure:
        # response = ce.get_cost_and_usage(
        #     TimePeriod={'Start': '2024-01-01', 'End': '2024-02-01'},
        #     Granularity='MONTHLY',
        #     Metrics=['UnblendedCost'],
        #     GroupBy=[
        #         {'Type': 'TAG', 'Key': 'Project'},
        #         {'Type': 'TAG', 'Key': 'Environment'}
        #     ]
        # )
        
        return report
    
    def enforce_tagging_policy(self, resource_type: str, resource_id: str) -> bool:
        """Enforce cost allocation tagging policy on a resource."""
        if resource_type == 'ec2':
            return self.tag_ec2_instance(resource_id, [])
        elif resource_type == 's3':
            return self.tag_s3_bucket(resource_id, [])
        elif resource_type == 'rds':
            return self.tag_rds_instance(resource_id, [])
        else:
            print(f"Unsupported resource type: {resource_type}")
            return False

# Usage example
if __name__ == "__main__":
    tag_manager = CostAllocationTagManager(region="us-east-1")
    
    # Define cost allocation tags
    cost_tags = [
        {'Key': 'Project', 'Value': 'WebApplication'},
        {'Key': 'Environment', 'Value': 'production'},
        {'Key': 'Owner', 'Value': 'john.doe@company.com'},
        {'Key': 'CostCenter', 'Value': 'CC12345'},
        {'Key': 'Department', 'Value': 'Engineering'},
        {'Key': 'Application', 'Value': 'frontend'},
        {'Key': 'BusinessUnit', 'Value': 'Tech'},
    ]
    
    # Tag a resource (example)
    instance_id = "i-1234567890abcdef0"
    tag_manager.tag_ec2_instance(instance_id, cost_tags)
    
    # Get tags
    tags = tag_manager.get_resource_tags(instance_id)
    print(f"Tags for {instance_id}: {tags}")

Pattern 8: Multi-Cloud Cost Aggregation

Multi-cloud cost aggregation provides unified visibility across AWS, Azure, and GCP.

BAD — Separate queries without normalization

# ❌ BAD — No normalization, separate tools for each cloud
# AWS
aws ce get-cost-and-usage --time-period Start=2024-01-01,End=2024-02-01

# Azure
az costmanagement query --type Usage --timeframe MonthToDate

# GCP
gcloud billing budgets describe --billing-account="012345-567890-ABCDEF"

GOOD — Unified multi-cloud cost aggregation framework

#!/bin/bash
# ✅ GOOD — Unified multi-cloud cost aggregation with normalization
set -euo pipefail

# Configuration
OUTPUT_DIR="${OUTPUT_DIR:-/tmp/cost-aggregation}"
START_DATE="${START_DATE:-$(date -d '1 month ago' +%Y-%m-%d)}"
END_DATE="${END_DATE:-$(date +%Y-%m-%d)}"

# Ensure output directory exists
mkdir -p "$OUTPUT_DIR"

# AWS Cost Aggregation
aggregate_aws_costs() {
  echo "Aggregating AWS costs..."
  
  aws ce get-cost-and-usage \
    --time-period "Start=${START_DATE},End=${END_DATE}" \
    --granularity MONTHLY \
    --metrics UnblendedCost \
    --group-by "Type=DIMENSION,Key=SERVICE" \
    --query 'ResultsByTime[].Total[].UnblendedCost Amount' \
    --output json > "$OUTPUT_DIR/aws_costs.json"
  
  # Extract total cost
  local aws_total=$(cat "$OUTPUT_DIR/aws_costs.json" | jq -r '.ResultsByTime[].Total.UnblendedCost.Amount' | awk '{sum+=$1} END {printf "%.2f", sum}')
  echo "AWS Total Cost: \$aws_total"
  echo "$aws_total" > "$OUTPUT_DIR/aws_total.txt"
}

# Azure Cost Aggregation
aggregate_azure_costs() {
  echo "Aggregating Azure costs..."
  
  local subscription_id=$(az account show --query id -o tsv)
  
  az costmanagement query \
    --type "Usage" \
    --timeframe "MonthToDate" \
    --dataset-aggregation '{"totalCost":{"name":"PreTaxCost","function":"Sum"}}' \
    --dataset-grouping '{"name":"ResourceGroup","type":"Dimension"}' \
    --subscription "$subscription_id" \
    --query "properties.rows[].properties.totalCost" \
    --output tsv > "$OUTPUT_DIR/azure_costs.txt"
  
  # Calculate total
  local azure_total=$(cat "$OUTPUT_DIR/azure_costs.txt" | awk '{sum+=$1} END {printf "%.2f", sum}')
  echo "Azure Total Cost: \$azure_total"
  echo "$azure_total" > "$OUTPUT_DIR/azure_total.txt"
}

# GCP Cost Aggregation
aggregate_gcp_costs() {
  echo "Aggregating GCP costs..."
  
  # Get billing account
  local billing_account=$(gcloud billing accounts list --format="value(name)" | head -1)
  
  # Query BigQuery for costs (requires Cloud Billing Export)
  gcloud bigquery queries run "
    SELECT 
      SUM(cost) as total_cost
    FROM 
      \`\${billing_account}.billing_data.gcp_billing_export_v1_012345\`
    WHERE 
      _PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  " --format="csv" > "$OUTPUT_DIR/gcp_costs.csv"
  
  # Extract total
  local gcp_total=$(tail -1 "$OUTPUT_DIR/gcp_costs.csv" | cut -d',' -f1)
  echo "GCP Total Cost: \$gcp_total"
  echo "$gcp_total" > "$OUTPUT_DIR/gcp_total.txt"
}

# Normalize all costs to USD
normalize_costs() {
  echo "Normalizing costs to USD..."
  
  # Get exchange rates (simplified - use actual rates API)
  local exchange_rates=(
    "USD:1.0"
    "EUR:1.08"
    "GBP:1.27"
    "JPY:0.0068"
  )
  
  # In production, use a real exchange rate API
  # For now, assume all costs are already in USD
  echo "1.0" > "$OUTPUT_DIR/eur_usd_rate.txt"
  echo "1.0" > "$OUTPUT_dir/gbp_usd_rate.txt"
  echo "1.0" > "$OUTPUT_DIR/jpy_usd_rate.txt"
  
  # Copy costs (already in USD)
  cp "$OUTPUT_DIR/aws_total.txt" "$OUTPUT_DIR/normalized_total.txt"
  cp "$OUTPUT_DIR/azure_total.txt" "$OUTPUT_DIR/normalized_azure.txt"
  cp "$OUTPUT_DIR/gcp_total.txt" "$OUTPUT_DIR/normalized_gcp.txt"
}

# Generate unified report
generate_unified_report() {
  echo "Generating unified cost report..."
  
  local aws_cost=$(cat "$OUTPUT_DIR/aws_total.txt" 2>/dev/null || echo "0")
  local azure_cost=$(cat "$OUTPUT_DIR/azure_total.txt" 2>/dev/null || echo "0")
  local gcp_cost=$(cat "$OUTPUT_DIR/gcp_total.txt" 2>/dev/null || echo "0")
  
  local total_cost=$(echo "$aws_cost + $azure_cost + $gcp_cost" | bc -l)
  
  echo ""
  echo "=============================================="
  echo "     Multi-Cloud Cost Aggregation Report"
  echo "=============================================="
  echo ""
  echo "Period: $START_DATE to $END_DATE"
  echo ""
  echo "Cost by Provider:"
  echo "  AWS:     \$aws_cost"
  echo "  Azure:   \$azure_cost"
  echo "  GCP:     \$gcp_cost"
  echo "  Total:   \$total_cost"
  echo ""
  echo "Cost Distribution:"
  if (( $(echo "$total_cost > 0" | bc -l) )); then
    local aws_pct=$(echo "scale=1; $aws_cost * 100 / $total_cost" | bc -l)
    local azure_pct=$(echo "scale=1; $azure_cost * 100 / $total_cost" | bc -l)
    local gcp_pct=$(echo "scale=1; $gcp_cost * 100 / $total_cost" | bc -l)
    echo "  AWS:     ${aws_pct}%"
    echo "  Azure:   ${azure_pct}%"
    echo "  GCP:     ${gcp_pct}%"
  fi
  echo ""
  echo "Report generated: $(date)"
  echo "=============================================="
  
  # Save report
  cat > "$OUTPUT_DIR/unified_report.txt" <<EOF
Multi-Cloud Cost Aggregation Report
====================================
Period: $START_DATE to $END_DATE

Cost by Provider:
  AWS:     \$aws_cost
  Azure:   \$azure_cost
  GCP:     \$gcp_cost
  Total:   \$total_cost

Cost Distribution:
  AWS:     ${aws_pct}%
  Azure:   ${azure_pct}%
  GCP:     ${gcp_pct}%

Report generated: $(date)
====================================
EOF
}

# Main execution
main() {
  echo "Starting multi-cloud cost aggregation..."
  echo "Date range: $START_DATE to $END_DATE"
  echo ""
  
  aggregate_aws_costs
  aggregate_azure_costs
  aggregate_gcp_costs
  normalize_costs
  generate_unified_report
  
  echo ""
  echo "Reports saved to: $OUTPUT_DIR"
}

main "$@"

Python Multi-Cloud Cost Aggregator

# ✅ GOOD — Python multi-cloud cost aggregator with normalization
import boto3
from datetime import datetime, timedelta
from typing import Dict, List, Optional
from dataclasses import dataclass
import statistics
import os

@dataclass
class CloudCost:
    provider: str
    amount: float
    currency: str
    period_start: datetime
    period_end: datetime
    breakdown: Optional[Dict[str, float]] = None

class MultiCloudCostAggregator:
    """Aggregates and normalizes costs across AWS, Azure, and GCP."""
    
    def __init__(self):
        self.aws_client = boto3.client('ce', region_name='us-east-1')
        self.aws_cost_explorer = boto3.client('ce', region_name='us-east-1')
        
        # Azure and GCP costs will be fetched via API/CLI
        self.azure_costs: List[Dict] = []
        self.gcp_costs: List[Dict] = []
        
        self.exchange_rates: Dict[str, float] = {
            'USD': 1.0,
            'EUR': 1.08,
            'GBP': 1.27,
            'JPY': 0.0068,
        }
    
    def get_aws_costs(self, days: int = 30) -> CloudCost:
        """Get AWS costs for the specified period."""
        end_date = datetime.utcnow().date()
        start_date = end_date - timedelta(days=days)
        
        try:
            response = self.aws_cost_explorer.get_cost_and_usage(
                TimePeriod={
                    'Start': start_date.isoformat(),
                    'End': end_date.isoformat()
                },
                Granularity='MONTHLY',
                Metrics=['UnblendedCost'],
                GroupBy=[
                    {'Type': 'DIMENSION', 'Key': 'SERVICE'},
                    {'Type': 'TAG', 'Key': 'Project'}
                ]
            )
            
            # Extract total cost
            total_cost = 0
            service_costs: Dict[str, float] = {}
            
            for result in response['ResultsByTime'][-1]['Groups']:
                amount = float(result['Metrics']['UnblendedCost']['Amount'])
                key = result['Keys'][0]  # Service name
                total_cost += amount
                service_costs[key] = service_costs.get(key, 0) + amount
            
            return CloudCost(
                provider='aws',
                amount=round(total_cost, 2),
                currency='USD',
                period_start=start_date,
                period_end=end_date,
                breakdown=service_costs,
            )
        except Exception as e:
            print(f"Error fetching AWS costs: {e}")
            return CloudCost(
                provider='aws',
                amount=0,
                currency='USD',
                period_start=start_date,
                period_end=end_date,
            )
    
    def get_azure_costs(self, days: int = 30) -> CloudCost:
        """Get Azure costs for the specified period."""
        # In production, use Azure Cost Management SDK
        # This is a simplified example
        
        from datetime import datetime
        end_date = datetime.utcnow().date()
        start_date = end_date - timedelta(days=days)
        
        try:
            # Example Azure Cost Management SDK usage
            # from azure.identity import DefaultAzureCredential
            # from azure.mgmt.costmanagement import CostManagementClient
            
            # For demo, return mock data
            azure_cost = 1500.0  # Example cost
            
            return CloudCost(
                provider='azure',
                amount=round(azure_cost, 2),
                currency='USD',  # Azure costs are typically in USD
                period_start=start_date,
                period_end=end_date,
            )
        except Exception as e:
            print(f"Error fetching Azure costs: {e}")
            return CloudCost(
                provider='azure',
                amount=0,
                currency='USD',
                period_start=start_date,
                period_end=end_date,
            )
    
    def get_gcp_costs(self, days: int = 30) -> CloudCost:
        """Get GCP costs for the specified period."""
        from datetime import datetime
        end_date = datetime.utcnow().date()
        start_date = end_date - timedelta(days=days)
        
        try:
            # Example GCP Billing API usage
            # from google.cloud import billing_v1
            # client = billing_v1.CloudBillingClient()
            
            # For demo, return mock data
            gcp_cost = 2000.0  # Example cost
            
            return CloudCost(
                provider='gcp',
                amount=round(gcp_cost, 2),
                currency='USD',  # GCP costs are typically in USD
                period_start=start_date,
                period_end=end_date,
            )
        except Exception as e:
            print(f"Error fetching GCP costs: {e}")
            return CloudCost(
                provider='gcp',
                amount=0,
                currency='USD',
                period_start=start_date,
                period_end=end_date,
            )
    
    def normalize_to_usd(self, amount: float, currency: str) -> float:
        """Normalize an amount to USD using exchange rates."""
        if currency == 'USD':
            return amount
        
        rate = self.exchange_rates.get(currency, 1.0)
        return round(amount * rate, 2)
    
    def aggregate_costs(self, days: int = 30) -> Dict:
        """Aggregate costs from all cloud providers."""
        aws_cost = self.get_aws_costs(days)
        azure_cost = self.get_azure_costs(days)
        gcp_cost = self.get_gcp_costs(days)
        
        # Normalize all costs to USD
        aws_usd = self.normalize_to_usd(aws_cost.amount, aws_cost.currency)
        azure_usd = self.normalize_to_usd(azure_cost.amount, azure_cost.currency)
        gcp_usd = self.normalize_to_usd(gcp_cost.amount, gcp_cost.currency)
        
        total_cost = aws_usd + azure_usd + gcp_usd
        
        return {
            'period': {
                'start': aws_cost.period_start.isoformat(),
                'end': aws_cost.period_end.isoformat(),
            },
            'providers': {
                'aws': {
                    'amount': aws_cost.amount,
                    'currency': aws_cost.currency,
                    'normalized_usd': aws_usd,
                    'breakdown': aws_cost.breakdown,
                },
                'azure': {
                    'amount': azure_cost.amount,
                    'currency': azure_cost.currency,
                    'normalized_usd': azure_usd,
                },
                'gcp': {
                    'amount': gcp_cost.amount,
                    'currency': gcp_cost.currency,
                    'normalized_usd': gcp_usd,
                },
            },
            'totals': {
                'total_usd': round(total_cost, 2),
                'aws_percentage': round((aws_usd / total_cost) * 100, 1) if total_cost > 0 else 0,
                'azure_percentage': round((azure_usd / total_cost) * 100, 1) if total_cost > 0 else 0,
                'gcp_percentage': round((gcp_usd / total_cost) * 100, 1) if total_cost > 0 else 0,
            },
        }
    
    def generate_cost_report(self, days: int = 30) -> str:
        """Generate a comprehensive cost report."""
        costs = self.aggregate_costs(days)
        
        report = [
            "=" * 80,
            "         Multi-Cloud Cost Aggregation Report",
            "=" * 80,
            "",
            f"Period: {costs['period']['start']} to {costs['period']['end']}",
            "",
            "Cost by Provider:",
            f"  AWS:     ${costs['providers']['aws']['normalized_usd']:,.2f} ({costs['providers']['aws']['amount']:.2f} {costs['providers']['aws']['currency']})",
            f"  Azure:   ${costs['providers']['azure']['normalized_usd']:,.2f} ({costs['providers']['azure']['amount']:.2f} {costs['providers']['azure']['currency']})",
            f"  GCP:     ${costs['providers']['gcp']['normalized_usd']:,.2f} ({costs['providers']['gcp']['amount']:.2f} {costs['providers']['gcp']['currency']})",
            "",
            f"  Total:   ${costs['totals']['total_usd']:,.2f}",
            "",
            "Cost Distribution:",
            f"  AWS:     {costs['totals']['aws_percentage']}%",
            f"  Azure:   {costs['totals']['azure_percentage']}%",
            f"  GCP:     {costs['totals']['gcp_percentage']}%",
            "",
        ]
        
        # AWS breakdown by service (if available)
        if costs['providers']['aws']['breakdown']:
            report.extend([
                "AWS Breakdown by Service:",
            ])
            for service, amount in sorted(costs['providers']['aws']['breakdown'].items(), key=lambda x: x[1], reverse=True)[:10]:
                pct = (amount / costs['providers']['aws']['normalized_usd']) * 100 if costs['providers']['aws']['normalized_usd'] > 0 else 0
                report.append(f"  {service}: ${amount:,.2f} ({pct:.1f}%)")
            report.append("")
        
        report.append("=" * 80)
        
        return "\n".join(report)

# Usage example
if __name__ == "__main__":
    aggregator = MultiCloudCostAggregator()
    report = aggregator.generate_cost_report(days=30)
    print(report)

Constraints

MUST DO

  • Normalize all cost data to a common currency (USD) before aggregation and comparison
  • Use at least 14 days of historical data for right-sizing recommendations to account for weekly patterns
  • Always layer spot instance recommendations with on-demand or reserved instances for critical workloads
  • Validate all cost allocation tags before applying them to resources
  • Set up automated alerts at 50%, 75%, 90%, and 100% of budget thresholds
  • Cross-reference utilization metrics with application SLAs before right-sizing
  • Document all optimization recommendations with ROI calculations and break-even periods
  • Regularly audit cost allocation tags for completeness and accuracy
  • Use reserved instance optimization for workloads with >70% utilization and stable patterns
  • Implement cost allocation at the resource level for granular chargeback

MUST NOT DO

  • Disable or bypass cost allocation tags to "speed up" deployments
  • Make right-sizing decisions based on single-point utilization metrics without trend analysis
  • Use spot instances for stateful, critical, or latency-sensitive workloads without proper interruption handling
  • Purchase reserved instances without historical usage validation and ROI analysis
  • Aggregate costs from different cloud providers without currency normalization
  • Ignore spot instance interruption rates when planning capacity
  • Apply cost allocation tags retroactively without considering data retention policies
  • Make optimization decisions without consulting application owners and SLA requirements
  • Disable monitoring and alerting during optimization implementation
  • Recommend spot instances for databases or services with strict uptime SLAs (>99.9%)

Output Template

When implementing cost optimization strategies, return the following structured output:

1. Executive Summary

Cost Optimization Analysis Report
=================================
Analysis Period: YYYY-MM-DD to YYYY-MM-DD
Total Estimated Monthly Savings: $X,XXX.XX
Implementation Timeline: X weeks
Projected ROI: XX%

2. Provider Breakdown

AWS:
  Current Monthly Cost: $X,XXX.XX
  Right-Sizing Savings: $XXX.XX (XX%)
  Spot Instance Savings: $XXX.XX (XX%)
  Reserved Instance Savings: $XXX.XX (XX%)
  Total Potential Savings: $XXX.XX (XX%)

Azure:
  Current Monthly Cost: $X,XXX.XX
  Right-Sizing Savings: $XXX.XX (XX%)
  Spot Instance Savings: $XXX.XX (XX%)
  Reserved Instance Savings: $XXX.XX (XX%)
  Total Potential Savings: $XXX.XX (XX%)

GCP:
  Current Monthly Cost: $X,XXX.XX
  Right-Sizing Savings: $XXX.XX (XX%)
  Spot Instance Savings: $XXX.XX (XX%)
  Reserved Instance Savings: $XXX.XX (XX%)
  Total Potential Savings: $XXX.XX (XX%)

3. Action Plan

Priority 1 (Week 1-2):
- Implement cost allocation tagging for all resources
- Set up automated cost alerts at 50%, 75%, 90%, 100% thresholds

Priority 2 (Week 3-4):
- Right-size low-utilization resources (CPU < 30% for 14 days)
- Implement spot instance strategy for fault-tolerant workloads

Priority 3 (Month 2):
- Purchase reserved instances for stable, high-utilization workloads
- Implement storage tier optimization

Priority 4 (Ongoing):
- Monthly cost reviews and optimization cycle
- Continuous right-sizing based on usage patterns

4. Risk Assessment

Spot Instance Risks:
- Interruption rate: XX% (based on historical data)
- Replacement time: X minutes average
- Mitigation: Maintain buffer capacity, use mixed instance types

Right-Sizing Risks:
- Performance impact: Low/Medium/High
- Application impact: Minimal/Moderate/Significant
- Mitigation: Gradual rollout, monitoring, rollback plan

Reserved Instance Risks:
- Commitment period: 1 or 3 years
- Early termination fees: XXX%
- Mitigation: Start with 1-year terms, monitor usage patterns

5. Monitoring Framework

Cost Alerts:
- 50% threshold: Informational notification
- 75% threshold: Manager notification
- 90% threshold: Emergency notification
- 100% threshold: Automatic budget freeze (optional)

Optimization Metrics:
- Monthly cost trend
- Cost per workload
- Cost per user
- ROI on optimization initiatives

Review Cadence:
- Daily: Automated cost anomaly detection
- Weekly: Team cost review
- Monthly: Executive cost report
- Quarterly: Optimization strategy review

Related Skills

SkillPurpose
cncf-cost-optimizationComplementary skill with different optimization focus; use this skill for detailed analysis and implementation
cncf-kubernetes-debuggingKubernetes cost optimization often requires debugging resource allocations and pod scheduling
agent-database-adminDatabase optimization is a key component of cloud cost management; use for RDS, Cloud SQL, Cosmos DB optimization

References

AWS Cost Optimization

Azure Cost Optimization

GCP Cost Optimization

General Cost Optimization


Additional Implementation Patterns

Pattern 9: Storage Tier Optimization

Optimize storage costs by analyzing access patterns and implementing appropriate tiering strategies.

BAD — No access pattern analysis

# ❌ BAD — No analysis, all data in expensive storage
# Just moving everything to S3 Intelligent-Tiering without analysis
aws s3api put-bucket-lifecycle-configuration \
  --bucket my-bucket \
  --lifecycle-configuration file://lifecycle.json

GOOD — Data-driven storage tier optimization

#!/bin/bash
# ✅ GOOD — Access pattern analysis for storage tier recommendations
set -euo pipefail

BUCKET="${1:-my-bucket}"
REGION="${AWS_REGION:-us-east-1}"

# Get bucket metrics
aws s3api get-bucket-metrics-configuration \
  --bucket "$BUCKET" \
  --id "StorageMetrics" \
  --query 'BucketMetricsConfiguration.StorageClassMetrics' \
  --output json 2>/dev/null || echo "Metrics not configured"

# Analyze access patterns
echo "=== Storage Tier Analysis for $BUCKET ==="
echo ""

# Check current lifecycle configuration
aws s3api get-bucket-lifecycle-configuration \
  --bucket "$BUCKET" \
  --query 'Rules[].{ID:ID,Status:Status,Transitions:Transitions}' \
  --output table 2>/dev/null || echo "No lifecycle configuration found"

# Get object count by size
echo ""
echo "Storage Distribution:"
aws s3api list-objects-v2 \
  --bucket "$BUCKET" \
  --query 'Contents[].{Key:Key,Size:Size,LastModified:LastModified}' \
  --max-items 100 \
  --output table 2>/dev/null | head -50

# Generate tier recommendations
echo ""
echo "=== Tier Recommendations ==="
echo "S3 Standard:      Objects accessed >= 1 time/month"
echo "S3 Intelligent:   Objects with variable access patterns"
echo "S3 Standard-IA:   Objects accessed < 1 time/month"
echo "S3 One-Zone IA:   Non-critical objects, < 1 access/month"
echo "S3 Glacier:       Objects accessed < 1 time/year"
echo "S3 Glacier Deep:  Objects accessed < 1 time/7 years"

Python Storage Optimization Engine

# ✅ GOOD — Python storage optimization with access pattern analysis
import boto3
from datetime import datetime, timedelta
from typing import Dict, List, Optional
from collections import defaultdict
import statistics

class StorageTierOptimizer:
    """Optimizes storage tier assignments based on access patterns."""
    
    def __init__(self, region: str = "us-east-1"):
        self.s3 = boto3.client('s3', region_name=region)
        self.cloudwatch = boto3.client('cloudwatch', region_name=region)
        
        # Access pattern thresholds (days since last access)
        self.thresholds = {
            'standard': 30,      # Accessed >= 1 time/month
            'standard_ia': 90,   # Accessed < 1 time/month
            'one_zone': 90,      # Non-critical, accessed < 1 time/month
            'glacier': 365,      # Accessed < 1 time/year
            'glacier_deep': 2555,  # Accessed < 1 time/7 years
        }
        
        self.tier_costs = {
            'standard': 0.023,        # $/GB/month
            'standard_ia': 0.0125,    # $/GB/month
            'one_zone': 0.0100,       # $/GB/month
            'glacier': 0.004,         # $/GB/month
            'glacier_deep': 0.00099,  # $/GB/month
        }
    
    def get_object_access_pattern(self, bucket: str, prefix: str = "") -> Dict[str, int]:
        """Get access patterns for objects in a bucket."""
        access_patterns = defaultdict(int)
        
        # List objects with pagination
        paginator = self.s3.get_paginator('list_objects_v2')
        page_iterator = paginator.paginate(Bucket=bucket, Prefix=prefix)
        
        for page in page_iterator:
            for obj in page.get('Contents', []):
                key = obj['Key']
                size = obj['Size']
                
                # Classify by size
                if size < 1024:  # < 1KB
                    access_patterns['tiny'] += 1
                elif size < 1024 * 1024:  # < 1MB
                    access_patterns['small'] += 1
                elif size < 1024 * 1024 * 1024:  # < 1GB
                    access_patterns['medium'] += 1
                else:
                    access_patterns['large'] += 1
        
        return dict(access_patterns)
    
    def analyze_bucket_storage(self, bucket: str) -> Dict:
        """Analyze bucket storage and recommend tier assignments."""
        try:
            # Get lifecycle configuration
            try:
                lifecycle = self.s3.get_bucket_lifecycle_configuration(Bucket=bucket)
                current_tiers = [rule['Transitions'][0]['StorageClass'] 
                               for rule in lifecycle.get('Rules', [])]
            except Exception:
                current_tiers = []
            
            # Get storage metrics
            metrics = self.cloudwatch.get_metric_statistics(
                Namespace='AWS/S3',
                MetricName='BucketSizeBytes',
                Dimensions=[
                    {'Name': 'BucketName', 'Value': bucket},
                    {'Name': 'StorageType', 'Value': 'StandardStorage'}
                ],
                StartTime=datetime.utcnow() - timedelta(days=30),
                EndTime=datetime.utcnow(),
                Period=86400,
                Statistics=['Average']
            )
            
            avg_size_bytes = statistics.mean([
                dp['Average'] for dp in metrics.get('Datapoints', [])
            ]) if metrics.get('Datapoints') else 0
            
            avg_size_gb = avg_size_bytes / (1024 ** 3)
            
            # Calculate potential savings
            current_cost = avg_size_gb * self.tier_costs['standard']
            
            # Recommend optimal tier based on size and access pattern
            if avg_size_gb < 100:
                recommended_tier = 'standard'
            elif avg_size_gb < 1000:
                recommended_tier = 'standard_ia'
            elif avg_size_gb < 10000:
                recommended_tier = 'one_zone'
            else:
                recommended_tier = 'glacier'
            
            recommended_cost = avg_size_gb * self.tier_costs[recommended_tier]
            savings = current_cost - recommended_cost
            savings_percentage = (savings / current_cost) * 100 if current_cost > 0 else 0
            
            return {
                'bucket': bucket,
                'current_size_gb': round(avg_size_gb, 2),
                'current_tier': 'Standard',
                'recommended_tier': recommended_tier,
                'current_cost_monthly': round(current_cost, 2),
                'recommended_cost_monthly': round(recommended_cost, 2),
                'monthly_savings': round(savings, 2),
                'savings_percentage': round(savings_percentage, 1),
                'tier_breakdown': {
                    'standard': round(avg_size_gb * 0.3, 2),
                    'standard_ia': round(avg_size_gb * 0.4, 2),
                    'one_zone': round(avg_size_gb * 0.2, 2),
                    'glacier': round(avg_size_gb * 0.1, 2),
                },
            }
        except Exception as e:
            print(f"Error analyzing bucket {bucket}: {e}")
            return {}
    
    def optimize_all_buckets(self) -> List[Dict]:
        """Optimize storage for all buckets."""
        buckets = self.s3.list_buckets()['Buckets']
        results = []
        
        for bucket in buckets:
            result = self.analyze_bucket_storage(bucket['Name'])
            if result:
                results.append(result)
        
        return results

# Usage example
if __name__ == "__main__":
    optimizer = StorageTierOptimizer(region="us-east-1")
    buckets = optimizer.optimize_all_buckets()
    
    print("Storage Tier Optimization Report")
    print("=" * 60)
    
    total_monthly_savings = 0
    
    for bucket in buckets:
        if bucket['savings_percentage'] > 10:
            print(f"\nBucket: {bucket['bucket']}")
            print(f"  Current Size: {bucket['current_size_gb']:.2f} GB")
            print(f"  Current Tier: {bucket['current_tier']}")
            print(f"  Recommended: {bucket['recommended_tier']}")
            print(f"  Monthly Savings: ${bucket['monthly_savings']:.2f}")
            total_monthly_savings += bucket['monthly_savings']
    
    print(f"\n" + "=" * 60)
    print(f"Total Monthly Savings: ${total_monthly_savings:.2f}")

Pattern 10: Kubernetes Resource Optimization

Optimize Kubernetes resource requests and limits to reduce cluster costs.

BAD — No resource optimization, default settings

# ❌ BAD — No resource analysis, just applying defaults
kubectl apply -f deployment.yaml
# Deployment has no resource requests/limits defined

GOOD — Kubernetes resource optimization with metrics

#!/bin/bash
# ✅ GOOD — Kubernetes resource optimization with metrics analysis
set -euo pipefail

NAMESPACE="${NAMESPACE:-default}"
DAYS_ANALYZED="${DAYS_ANALYZED:-14}"

echo "=== Kubernetes Resource Optimization ==="
echo "Namespace: $NAMESPACE"
echo "Analysis Period: $DAYS_ANALYZED days"
echo ""

# Get all deployments
deployments=$(kubectl get deployments -n "$NAMESPACE" -o jsonpath='{.items[*].metadata.name}')

for deployment in $deployments; do
  echo "Analyzing deployment: $deployment"
  
  # Get pod resource usage (requires metrics server)
  kubectl top pods -n "$NAMESPACE" -l "app=$deployment" 2>/dev/null || echo "Metrics not available"
  
  # Get deployment resource configuration
  echo "Current resource configuration:"
  kubectl get deployment "$deployment" -n "$NAMESPACE" \
    -o jsonpath='{.spec.template.spec.containers[*].resources}' 2>/dev/null || echo "No resources defined"
  
  echo ""
done

# Generate recommendations
echo "=== Optimization Recommendations ==="
echo "1. Set CPU requests to 50-70% of measured peak"
echo "2. Set CPU limits to 150-200% of requests"
echo "3. Set memory requests to 70-80% of measured peak"
echo "4. Set memory limits to 150-200% of requests"
echo "5. Use Vertical Pod Autoscaler for automatic optimization"

Python K8s Resource Optimizer

# ✅ GOOD — Python K8s resource optimizer with metrics
import subprocess
import json
from datetime import datetime, timedelta
from typing import Dict, List, Optional
from dataclasses import dataclass
import statistics

@dataclass
class PodMetrics:
    name: str
    cpu_usage: float  # millicores
    memory_usage: float  # MB
    cpu_request: Optional[float] = None
    memory_request: Optional[float] = None
    cpu_limit: Optional[float] = None
    memory_limit: Optional[float] = None

class K8sResourceOptimizer:
    """Optimizes Kubernetes resource requests and limits."""
    
    def __init__(self):
        self.metrics_server_available = self._check_metrics_server()
    
    def _check_metrics_server(self) -> bool:
        """Check if metrics server is available."""
        try:
            result = subprocess.run(
                ['kubectl', 'get', 'apiservice', 'v1beta1.metrics.k8s.io', '-o', 'jsonpath={.status.conditions[0].status}'],
                capture_output=True, text=True
            )
            return result.stdout.strip() == 'True'
        except Exception:
            return False
    
    def get_pod_metrics(self, namespace: str, pod: str) -> Optional[PodMetrics]:
        """Get resource metrics for a pod."""
        if not self.metrics_server_available:
            return None
        
        try:
            result = subprocess.run(
                ['kubectl', 'top', 'pod', pod, '-n', namespace, '--no-headers', '-o', 'json'],
                capture_output=True, text=True, check=True
            )
            metrics = json.loads(result.stdout)
            
            return PodMetrics(
                name=pod,
                cpu_usage=metrics.get('usage', {}).get('cpu', '0').rstrip('n') or '0',
                memory_usage=metrics.get('usage', {}).get('memory', '0').rstrip('Ki') or '0',
            )
        except Exception as e:
            print(f"Error getting metrics for {pod}: {e}")
            return None
    
    def get_deployment_resources(self, namespace: str, deployment: str) -> Dict:
        """Get resource configuration for a deployment."""
        try:
            result = subprocess.run(
                ['kubectl', 'get', 'deployment', deployment, '-n', namespace, '-o', 'json'],
                capture_output=True, text=True, check=True
            )
            deployment_data = json.loads(result.stdout)
            
            containers = []
            for container in deployment_data['spec']['template']['spec'].get('containers', []):
                resources = container.get('resources', {})
                containers.append({
                    'name': container['name'],
                    'requests': resources.get('requests', {}),
                    'limits': resources.get('limits', {}),
                })
            
            return {'containers': containers}
        except Exception as e:
            print(f"Error getting resources for {deployment}: {e}")
            return {'containers': []}
    
    def calculate_optimal_resources(self, metrics: List[PodMetrics]) -> Dict[str, float]:
        """Calculate optimal resource requests and limits based on metrics."""
        if not metrics:
            return {}
        
        cpu_values = [m.cpu_usage for m in metrics]
        memory_values = [m.memory_usage for m in metrics]
        
        # Use 70th percentile for requests
        cpu_70th = sorted(cpu_values)[int(len(cpu_values) * 0.7)] if cpu_values else 0
        memory_70th = sorted(memory_values)[int(len(memory_values) * 0.7)] if memory_values else 0
        
        # Use 95th percentile for limits
        cpu_95th = sorted(cpu_values)[int(len(cpu_values) * 0.95)] if cpu_values else 0
        memory_95th = sorted(memory_values)[int(len(memory_values) * 0.95)] if memory_values else 0
        
        return {
            'cpu_request': round(cpu_70th * 0.7, 0),  # 70% of 70th percentile
            'cpu_limit': round(cpu_95th * 1.5, 0),
            'memory_request': round(memory_70th * 0.7, 0),
            'memory_limit': round(memory_95th * 1.5, 0),
        }
    
    def analyze_namespace(self, namespace: str) -> List[Dict]:
        """Analyze resource optimization for all pods in a namespace."""
        if not self.metrics_server_available:
            return [{'error': 'Metrics server not available'}]
        
        try:
            result = subprocess.run(
                ['kubectl', 'get', 'pods', '-n', namespace, '-o', 'jsonpath={.items[*].metadata.name}'],
                capture_output=True, text=True, check=True
            )
            pods = result.stdout.split()
            
            results = []
            for pod in pods:
                metrics = self.get_pod_metrics(namespace, pod)
                if metrics:
                    optimal = self.calculate_optimal_resources([metrics])
                    
                    # Calculate potential savings
                    current_cpu = metrics.cpu_limit or 500  # Default
                    current_memory = metrics.memory_limit or 512  # Default
                    
                    optimal_cpu = optimal.get('cpu_limit', current_cpu)
                    optimal_memory = optimal.get('memory_limit', current_memory)
                    
                    # Estimate cost savings (simplified)
                    cpu_savings = (current_cpu - optimal_cpu) * 0.000011  # $ per millicore per hour
                    memory_savings = (current_memory - optimal_memory) * 0.0000037  # $ per MB per hour
                    
                    monthly_savings = (cpu_savings + memory_savings) * 730
                    
                    results.append({
                        'pod': pod,
                        'current_cpu': current_cpu,
                        'current_memory': current_memory,
                        'optimal_cpu': optimal_cpu,
                        'optimal_memory': optimal_memory,
                        'monthly_savings': round(monthly_savings, 2),
                        'metrics': metrics,
                    })
            
            return results
        except Exception as e:
            return [{'error': str(e)}]
    
    def optimize_all_namespaces(self) -> Dict[str, List[Dict]]:
        """Optimize resources across all namespaces."""
        try:
            result = subprocess.run(
                ['kubectl', 'get', 'namespaces', '-o', 'jsonpath={.items[*].metadata.name}'],
                capture_output=True, text=True, check=True
            )
            namespaces = result.stdout.split()
            
            results = {}
            for namespace in namespaces:
                if namespace not in ['kube-system', 'kube-public', 'kube-node-lease']:
                    results[namespace] = self.analyze_namespace(namespace)
            
            return results
        except Exception as e:
            return {'error': str(e)}

# Usage example
if __name__ == "__main__":
    optimizer = K8sResourceOptimizer()
    
    # Get current namespace
    try:
        result = subprocess.run(
            ['kubectl', 'config', 'get-contexts', '--output', 'name'],
            capture_output=True, text=True, check=True
        )
        current_context = result.stdout.strip().split('*')[-1].strip()
    except Exception:
        current_context = "default"
    
    print("Kubernetes Resource Optimization")
    print("=" * 60)
    print(f"Current Context: {current_context}")
    
    results = optimizer.analyze_namespace(current_context)
    
    total_monthly_savings = 0
    
    for result in results:
        if 'monthly_savings' in result:
            if result['monthly_savings'] > 10:
                print(f"\nPod: {result['pod']}")
                print(f"  Current CPU: {result['current_cpu']}m")
                print(f"  Optimal CPU: {result['optimal_cpu']}m")
                print(f"  Monthly Savings: ${result['monthly_savings']:.2f}")
                total_monthly_savings += result['monthly_savings']
    
    print(f"\n" + "=" * 60)
    print(f"Total Monthly Savings: ${total_monthly_savings:.2f}")

References

Gespeicherte Skills