FinOps Kültürü ve Bulut Maliyet Yönetimi: Ekipler Arası İş Birliğiyle Tasarruf

Bulut faturanız her ay biraz daha şişiyor, ekipler ne kadar harcandığını bilmiyor ve maliyet optimizasyonu denilince herkes birbirinin yüzüne bakıyor. Tanıdık bir senaryo, değil mi? İşte tam bu noktada FinOps devreye giriyor. FinOps, yani Financial Operations, teknik bir araç değil; bir kültür değişiklidir. Ve bu kültürü benimsemeden hiçbir araç sizi kurtaramaz.

FinOps Nedir ve Neden Önemlidir?

FinOps’u basitçe “bulut maliyet yönetimi” olarak tanımlamak eksik kalır. Daha doğru bir tanım şu olur: mühendislik, finans ve iş birimlerinin birlikte çalışarak bulut harcamalarını optimize ettiği bir işletme kültürü. FinOps Foundation’ın tanımıyla “bulut kullanımından maksimum iş değeri elde etmek için çapraz fonksiyonlu ekiplerin iş birliği” diyebiliriz.

Geleneksel IT bütçelemesinde harcamalar merkezi bir birim tarafından kontrol edilirdi. Bulut gelince bu model çöktü. Artık bir geliştirici öğleden sonra saat ikide bir Kubernetes cluster açıp farkında bile olmadan aylık binlerce dolarlık maliyet yaratabilir. FinOps bu kaosa düzen getirmek için vardır.

Üç temel prensip üzerine kuruludur:

  • Görünürlük: Kim ne harcıyor, neden harcıyor?
  • Optimizasyon: Gereksiz veya aşırı boyutlandırılmış kaynakları tespit etmek
  • Hesap verebilirlik: Maliyetlerin doğru ekiplere atfedilmesi

Maliyet Görünürlüğü: Her Şeyin Başlangıcı

FinOps yolculuğu görünürlükle başlar. Neyi ölçemiyorsanız onu yönetemezsiniz. AWS, Azure ve GCP’nin hepsinde faturalandırma verileri ham halde mevcuttur ama bu veriyi anlamlı hale getirmek iş gerektirir.

Etiketleme Stratejisi

Bulut kaynaklarınızı etiketlemeden (tagging) gerçek maliyet attributionı yapamazsınız. Ekiplere, projelere, ortamlara göre etiket standardı oluşturmak şart.

Örnek bir AWS etiket politikası şu şekilde olabilir:

# AWS CLI ile mevcut etiketlenmemiş EC2 instance'larını bul
aws ec2 describe-instances 
  --query 'Reservations[*].Instances[?!Tags || length(Tags[?Key==`Environment`]) == `0`].[InstanceId, InstanceType]' 
  --output table

# Toplu etiket ekleme
aws ec2 create-tags 
  --resources i-1234567890abcdef0 
  --tags Key=Environment,Value=production 
         Key=Team,Value=platform 
         Key=Project,Value=api-gateway 
         Key=CostCenter,Value=engineering-001

Etiketleme standartlarını zorlamak için AWS Tag Policies veya Azure Policy kullanabilirsiniz. Ama bence daha pratik olan yol, Terraform veya Pulumi gibi IaC araçlarında zorunlu etiket değişkenleri tanımlamaktır. Böylece deployment sırasında etiket eksikse pipeline doğrudan hata verir.

# Terraform ile zorunlu etiket kontrolü - variables.tf
variable "mandatory_tags" {
  description = "Tum kaynaklar icin zorunlu etiketler"
  type = object({
    environment = string
    team        = string
    project     = string
    cost_center = string
  })
  validation {
    condition     = contains(["production", "staging", "development"], var.mandatory_tags.environment)
    error_message = "Environment 'production', 'staging' veya 'development' olmali."
  }
}

Maliyet Verilerini Çekmek ve Analiz Etmek

AWS Cost Explorer API’si ile programatik olarak maliyet analizi yapabilirsiniz. Özellikle anomali tespiti için bu veriler altın değerindedir.

# AWS CLI ile servis bazlı aylık maliyet raporu
aws ce get-cost-and-usage 
  --time-period Start=2024-01-01,End=2024-02-01 
  --granularity MONTHLY 
  --metrics "BlendedCost" "UsageQuantity" 
  --group-by Type=DIMENSION,Key=SERVICE 
  --query 'ResultsByTime[0].Groups[*].[Keys[0], Metrics.BlendedCost.Amount]' 
  --output table

# Tag bazlı maliyet breakdown
aws ce get-cost-and-usage 
  --time-period Start=2024-01-01,End=2024-02-01 
  --granularity MONTHLY 
  --metrics "BlendedCost" 
  --group-by Type=TAG,Key=Team 
  --filter '{"Dimensions": {"Key": "SERVICE", "Values": ["Amazon EC2"]}}' 
  --output json

Bu verileri bir S3 bucket’a aktarıp Athena ile sorgulamak ya da bir dashboard aracına (Grafana, Metabase) bağlamak pratik bir yaklaşım. Özellikle büyük ortamlarda manuel Cost Explorer kullanımı yetersiz kalıyor.

Maliyet Optimizasyon Teknikleri

Görünürlüğü sağladıktan sonra sıra optimizasyona geliyor. Burada low-hanging fruit dediğimiz kolay kazanımlar genellikle şunlardır:

Rightsizing: Doğru Boyutlandırma

Çoğu ortamda EC2 instance’larının yüzde ellisinden fazlası aşırı boyutlandırılmıştır. Birisi “güvenli tarafta kalalım” demiş, m5.2xlarge açmış ve CPU kullanımı sürekli yüzde sekizde gidiyor.

# AWS Compute Optimizer önerilerini çek
aws compute-optimizer get-ec2-instance-recommendations 
  --filters name=Finding,values=OVER_PROVISIONED 
  --query 'instanceRecommendations[*].[instanceArn, finding, recommendationOptions[0].instanceType]' 
  --output table

# CloudWatch ile son 2 haftanın ortalama CPU kullanımını sorgula
aws cloudwatch get-metric-statistics 
  --namespace AWS/EC2 
  --metric-name CPUUtilization 
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 
  --start-time 2024-01-15T00:00:00Z 
  --end-time 2024-01-29T00:00:00Z 
  --period 86400 
  --statistics Average Maximum 
  --output table

Eğer ortalama CPU yüzde on beşin altında, memory da benzer durumdaysa o instance’ı bir sonraki boyuta düşürmek genellikle güvenlidir. Tabii önce yük testleri ve monitoring verilerine bakın.

Reserved Instances ve Savings Plans

Bu ikisi doğru kullanıldığında EC2 maliyetlerinde yüzde otuzdan yüzde altmışa kadar tasarruf sağlar. Ama dikkat: commit verdiğiniz için yanlış seçim yaparsanız tasarruf değil kayıp yaşarsınız.

Genel kural şudur: temel (baseline) yükünüz için Reserved Instance veya Savings Plans, değişken yükler için On-Demand veya Spot Instance kullanın.

# Mevcut Reserved Instance kullanim durumunu kontrol et
aws ce get-reservation-utilization 
  --time-period Start=2024-01-01,End=2024-02-01 
  --granularity MONTHLY 
  --query 'UtilizationsByTime[0].Total' 
  --output json

# Savings Plans coverage analizi
aws ce get-savings-plans-coverage 
  --time-period Start=2024-01-01,End=2024-02-01 
  --granularity MONTHLY 
  --output json

Utilization yüzde yetmişin altına düştüyse ya fazla RI aldınız ya da workload’unuz değişti. Bu durumda AWS Marketplace’te RI satışı yapabilirsiniz.

Spot Instance Kullanımı

Batch işleri, CI/CD runner’ları, stateless web katmanları için Spot Instance kullanmak büyük tasarruf demektir. Yüzde doksana kadar indirim mümkün.

# Spot Instance fiyat geçmişini kontrol et (hangi AZ daha stabil)
aws ec2 describe-spot-price-history 
  --instance-types m5.large m5.xlarge 
  --product-descriptions "Linux/UNIX" 
  --start-time 2024-01-22T00:00:00Z 
  --query 'SpotPriceHistory[*].[InstanceType, AvailabilityZone, SpotPrice, Timestamp]' 
  --output table

# Spot interruption oranını dusuk tutan instance type'lari bulmak icin
# AWS Spot Instance Advisor API kullan
curl -s "https://spot-price.s3.amazonaws.com/spot.js" | 
  python3 -c "
import sys, json
data = sys.stdin.read()
data = data[data.index('{'): data.rindex('}')+1]
parsed = json.loads(data)
print(json.dumps(parsed, indent=2))
" | grep -A2 '"m5.large"'

Idle ve Zombie Kaynaklar

Her ortamda “unutulmuş” kaynaklar vardır. Biri test için bir şey açmış, iş bitmiş, kaynak çalışmaya devam ediyor. Bu kaynakları tespit etmek için düzenli tarama şart.

#!/bin/bash
# idle-resources-scan.sh
# Son 7 gunde kullanilmayan EC2 instance'larini bul

echo "=== Son 7 Gunde Dusuk CPU Kullanan Instance'lar ==="
aws ec2 describe-instances 
  --filters "Name=instance-state-name,Values=running" 
  --query 'Reservations[*].Instances[*].[InstanceId, InstanceType, Tags[?Key==`Name`].Value | [0]]' 
  --output text | while read instance_id instance_type name; do
    avg_cpu=$(aws cloudwatch get-metric-statistics 
      --namespace AWS/EC2 
      --metric-name CPUUtilization 
      --dimensions Name=InstanceId,Value=$instance_id 
      --start-time $(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZ) 
      --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) 
      --period 604800 
      --statistics Average 
      --query 'Datapoints[0].Average' 
      --output text 2>/dev/null)
    
    if [ "$avg_cpu" != "None" ] && (( $(echo "$avg_cpu < 5.0" | bc -l) )); then
      echo "IDLE: $instance_id ($instance_type) - Name: $name - Avg CPU: $avg_cpu%"
    fi
done

echo ""
echo "=== Unattached EBS Volume'lari ==="
aws ec2 describe-volumes 
  --filters "Name=status,Values=available" 
  --query 'Volumes[*].[VolumeId, Size, VolumeType, CreateTime]' 
  --output table

echo ""
echo "=== Kullanilmayan Elastic IP'ler ==="
aws ec2 describe-addresses 
  --query 'Addresses[?!InstanceId].[PublicIp, AllocationId]' 
  --output table

Bu scripti bir Lambda’ya koyup her hafta Slack’e rapor göndertebilirsiniz. Ekibin “ah bu var mıydı hala?” dediği şeyleri keşfetmek için idealdir.

FinOps Kültürünü Organizasyona Yaymak

Teknik araçlar hazır, peki ya kültür? İşte burada asıl zorluk başlıyor.

Showback ve Chargeback

Showback: “Takım, bu ay 8.500 dolar harcadınız, sadece bilginize.” Fatura ödemeye devam, ama herkes ne kadar harcadığını biliyor.

Chargeback: Maliyet gerçekten ilgili ekibin bütçesinden düşülüyor. Bu daha güçlü bir mekanizma ama organizasyonel olgunluk gerektiriyor.

Küçük ekiplerle başlıyorsanız showback’i öneririm. Ekipler rakamları görünce davranışları kendiliğinden değişmeye başlar. “Bizim geliştirme ortamı neden production’dan pahalı?” sorusu sormaya başlıyorlar, bu iyi bir işaret.

Maliyet Anomali Tespiti

AWS Cost Anomaly Detection servisini mutlaka kullanın. Beklenmedik maliyet artışlarını anında yakalar.

# Anomaly Monitor oluştur (servis bazlı)
aws ce create-anomaly-monitor 
  --anomaly-monitor '{
    "MonitorName": "ServiceMonitor",
    "MonitorType": "DIMENSIONAL",
    "MonitorDimension": "SERVICE"
  }'

# Anomaly Subscription - Slack veya email bildirimi
aws ce create-anomaly-subscription 
  --anomaly-subscription '{
    "SubscriptionName": "DailyAnomalyAlert",
    "MonitorArnList": ["arn:aws:ce::123456789012:anomalymonitor/abcd1234"],
    "Subscribers": [
      {
        "Address": "[email protected]",
        "Type": "EMAIL"
      }
    ],
    "Threshold": 20,
    "Frequency": "DAILY"
  }'

Yüzde yirmi eşiği başlangıç için makul. Çok düşük ayarlarsanız alert yorgunluğu yaşarsınız.

Bütçe Alarmları

Her proje ve ortam için bütçe alarm tanımlamak basit ama etkili bir önlem.

# AWS Budgets ile aylık EC2 butce alarmi
aws budgets create-budget 
  --account-id 123456789012 
  --budget '{
    "BudgetName": "EC2-Production-Monthly",
    "BudgetLimit": {
      "Amount": "5000",
      "Unit": "USD"
    },
    "TimeUnit": "MONTHLY",
    "BudgetType": "COST",
    "CostFilters": {
      "Service": ["Amazon EC2"],
      "TagKeyValue": ["user:Environment$production"]
    }
  }' 
  --notifications-with-subscribers '[
    {
      "Notification": {
        "NotificationType": "ACTUAL",
        "ComparisonOperator": "GREATER_THAN",
        "Threshold": 80
      },
      "Subscribers": [
        {
          "SubscriptionType": "EMAIL",
          "Address": "[email protected]"
        }
      ]
    },
    {
      "Notification": {
        "NotificationType": "FORECASTED",
        "ComparisonOperator": "GREATER_THAN",
        "Threshold": 100
      },
      "Subscribers": [
        {
          "SubscriptionType": "EMAIL",
          "Address": "[email protected]"
        }
      ]
    }
  ]'

Yüzde seksen gerçek harcama ve yüzde yüz tahmin uyarısı en yaygın konfigürasyon. Böylece hem mevcut durumu hem de ay sonu tahmini yakında tutarsınız.

Kubernetes Maliyet Yönetimi

Kubernetes ortamlarında maliyet görünürlüğü daha da zordur. Node bazlı faturalandırma var ama hangi pod ne kadar tüketiyor belli değil. Bunun için Kubecost veya OpenCost gibi araçlar kullanılmalı.

# Kubecost CLI ile namespace bazli maliyet raporu
kubectl cost namespace 
  --window 7d 
  --show-cpu 
  --show-memory 
  --show-efficiency

# Resource request vs actual kullanim farki
kubectl top pods --all-namespaces --sort-by=cpu | head -20

# Oversized deployment'lari bul - request cok fazla, actual az
kubectl get pods --all-namespaces -o json | 
  jq -r '.items[] | 
    select(.spec.containers[0].resources.requests.cpu != null) |
    [.metadata.namespace, .metadata.name, 
     .spec.containers[0].resources.requests.cpu,
     .spec.containers[0].resources.requests.memory] | 
    @tsv'

Kubernetes’te Vertical Pod Autoscaler (VPA) ve Horizontal Pod Autoscaler (HPA) doğru ayarlandığında hem performans hem maliyet açısından önemli kazanımlar sağlar. VPA’yı önce “Off” modunda çalıştırıp öneri verdiğin ama uygulamadığı moda ayarlayın, bir süre sonra önerilere bakıp manuel güncelleyin. Doğrudan “Auto” moda almak prod ortamda riskli olabilir.

Pratik FinOps Ritüelleri

Kültür değişikliği için düzenli toplantılar ve ritüeller şart:

  • Haftalık maliyet review: Ekip leads ile 15 dakika, geçen haftanın harcamaları, anomaliler
  • Aylık optimizasyon sprint: Her sprint’te bir miktar kapasiteyi maliyet optimizasyonuna ayırın
  • Quarterly RI/SP review: Commitment seviyelerini gözden geçirin
  • Yıllık mimari gözden geçirme: Büyük tasarruf fırsatları için mimari değişikliklere bakın

Ekipler için “cloud cost champion” rolü tanımlamak da işe yarıyor. Her ekipten birisi bu konuyu sahipleniyor, düzenli rapor üretiyor.

Gerçek Dünya Senaryosu: Data Pipeline Maliyetini Düşürmek

Bir müşteri projesinde günlük çalışan bir data pipeline’ı vardı. EMR cluster sabah altıda başlıyor, öğle ikiye kadar çalışıyor, kapatılmayı unutuyorlardı. Günde sekiz saatten fazla boşta çalışıyordu.

Çözüm basitti: pipeline sonunda otomatik cluster termination, Spot Instance kullanımı ve rightsizing. Aylık 4.200 dolar olan maliyet 980 dolara düştü. Yüzde yetmiş yedi tasarruf. Kimsenin zor bir şey yapmasına gerek yoktu, sadece görünürlük ve küçük bir otomasyon.

# EMR cluster'i is bittikten sonra otomatik kapat
aws emr create-cluster 
  --name "daily-pipeline-$(date +%Y%m%d)" 
  --release-label emr-6.10.0 
  --instance-groups '[
    {"InstanceRole":"MASTER","InstanceType":"m5.xlarge","InstanceCount":1},
    {"InstanceRole":"CORE","InstanceType":"m5.2xlarge","InstanceCount":2,
     "BidPrice":"0.15"}
  ]' 
  --auto-terminate 
  --steps '[{
    "Name":"Run Pipeline",
    "ActionOnFailure":"TERMINATE_CLUSTER",
    "HadoopJarStep":{
      "Jar":"command-runner.jar",
      "Args":["spark-submit","s3://bucket/pipeline.py"]
    }
  }]' 
  --use-default-roles

--auto-terminate flag’i son adım bitince cluster’ı otomatik kapatır. Tek satır ekleme, büyük tasarruf.

Araç Seçimi

FinOps için kullanabileceğiniz araçlar:

  • AWS native: Cost Explorer, Cost Anomaly Detection, Budgets, Compute Optimizer, Trusted Advisor
  • GCP native: Cost Management, Recommender, Cloud Billing Reports
  • Azure native: Cost Management + Billing, Advisor
  • Çok bulutlu: CloudHealth, Apptio Cloudability, Spot.io
  • Açık kaynak: Infracost (IaC maliyet tahmini), OpenCost (Kubernetes), Cloud Custodian (politika tabanlı yönetim)

Özellikle Infracost‘u CI/CD pipeline’ına entegre etmeyi öneririm. PR açıldığında “bu değişiklik aylık maliyeti 340 dolar artıracak” gibi bir yorum otomatik olarak geliyor. Geliştirici bilinçleniyor.

Sonuç

FinOps bir ürün değil, bir yolculuk. Araçları kurmak kolay, kültürü değiştirmek zor. Ama şunu net söyleyeyim: görünürlük olmadan optimizasyon olmaz, hesap verebilirlik olmadan sürdürülebilir tasarruf olmaz.

Başlangıç için şu sırayı öneriyorum:

  • Önce etiketleme standardını oturun ve uygulayın
  • Bütçe alarmları ve anomali tespitini devreye alın
  • Idle kaynakları temizleyin (hızlı kazanım)
  • Ekiplere showback raporları gönderin
  • Sonra RI/Savings Plans değerlendirin
  • Son olarak mimari seviyede optimizasyonlara bakın

Bulut faturası sizi yönetmeye başladığında iş işten geçmiş demektir. Sizi bulut faturasını yönetiyor olmak istiyorsunuz. Bunun için teknik bilgi kadar organizasyonel disiplin de gerekiyor. İkisini bir araya getirdiğinizde sonuçlar gerçekten etkileyici oluyor.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir