Reserved Instance ve Savings Plans ile Bulut Maliyetlerini Azaltın

Bulut faturanıza her ay baktığınızda içiniz sıkışıyorsa, yalnız değilsiniz. AWS, Azure veya GCP kullanıyor olun, on-demand fiyatlandırmayla çalışmak uzun vadede cebinizi ciddi şekilde yakar. Ama iyi haber şu: Reserved Instance (RI) ve Savings Plans gibi taahhüt tabanlı modeller, doğru kullanıldığında yüzde 30 ile yüzde 72 arasında tasarruf sağlayabilir. Bu yazıda bu mekanizmaları gerçek dünya senaryolarıyla, pratik komutlarla ve hesaplamalarla ele alacağız.

Önce Temel Kavramları Netleştirelim

Reserved Instance, belirli bir instance tipi, bölge ve işletim sistemi için 1 veya 3 yıllık taahhüt karşılığında indirim almanızı sağlar. Savings Plans ise daha esnek bir yapıya sahip; saatlik dolar cinsinden harcama taahhüdü verirsiniz ve bu taahhüt karşılığında indirim alırsınız.

Reserved Instance türleri:

  • Standard RI: En yüksek indirim, değişiklik imkanı en düşük
  • Convertible RI: Daha düşük indirim ama instance tipi veya işletim sistemini değiştirebilirsiniz
  • Scheduled RI: Belirli zaman dilimlerinde çalışacak workload’lar için (AWS artık bu ürünü aktif olarak satmıyor)

Savings Plans türleri:

  • Compute Savings Plans: EC2, Fargate ve Lambda’yı kapsar, en esnek seçenek
  • EC2 Instance Savings Plans: Belirli instance ailesi ve bölge için, daha yüksek indirim
  • SageMaker Savings Plans: ML workload’ları için ayrı kategori

Şimdi asıl meseleye girelim: hangi durumda ne kullanırsınız ve nasıl optimize edersiniz.

Mevcut Harcamalarınızı Anlamak

Herhangi bir taahhüt vermeden önce mevcut kullanım profilinizi iyi anlamanız gerekiyor. AWS Cost Explorer bu noktada hayat kurtarır.

# AWS CLI ile son 30 günün EC2 maliyetini çekin
aws ce get-cost-and-usage 
  --time-period Start=2024-11-01,End=2024-12-01 
  --granularity MONTHLY 
  --filter '{"Dimensions": {"Key": "SERVICE", "Values": ["Amazon EC2"]}}' 
  --metrics "BlendedCost" "UsageQuantity" 
  --group-by Type=DIMENSION,Key=INSTANCE_TYPE 
  --output json | jq '.ResultsByTime[0].Groups[] | {instance: .Keys[0], cost: .Metrics.BlendedCost.Amount}'

Bu komut size hangi instance tiplerinde ne kadar harcadığınızı gösterir. Çıktıyı bir kenara not edin.

# Rezervasyon kapsamı (coverage) raporunu çekin
aws ce get-reservation-coverage 
  --time-period Start=2024-11-01,End=2024-12-01 
  --granularity MONTHLY 
  --output json | jq '.Total.CoverageHours.CoverageHoursPercentage'

Bu çıktı size mevcut rezervasyonlarınızın workload’ınızın ne kadarını karşıladığını söyler. Yüzde 60’ın altındaysanız ciddi optimizasyon fırsatı var demektir.

# Kullanılmayan Reserved Instance'ları tespit edin
aws ce get-reservation-utilization 
  --time-period Start=2024-11-01,End=2024-12-01 
  --granularity MONTHLY 
  --output json | jq '.Total.UtilizationPercentage'

Rezervasyon kullanım oranı yüzde 85’in altındaysa, ya fazla rezervasyon almışsınız ya da workload profiliniz değişmiş demektir. Bu durumda Reserved Instance Marketplace üzerinden satış yapabilirsiniz.

AWS Cost Explorer Tavsiyeleri

AWS, kullanım geçmişinize bakarak otomatik tavsiyeler üretir. Ama bu tavsiyeleri körü körüne uygulamak yerine anlamak önemli.

# RI satın alma tavsiyelerini çekin
aws ce get-reservation-purchase-recommendation 
  --service "Amazon EC2" 
  --lookback-period-in-days SIXTY_DAYS 
  --term-in-years ONE_YEAR 
  --payment-option PARTIAL_UPFRONT 
  --output json | jq '.Recommendations[] | {
    instanceType: .RecommendationDetails[0].InstanceDetails.EC2InstanceDetails.InstanceType,
    region: .RecommendationDetails[0].InstanceDetails.EC2InstanceDetails.Region,
    recommendedCount: .RecommendationDetails[0].RecommendedNumberOfInstancesToPurchase,
    estimatedMonthlySavings: .RecommendationSummary.TotalEstimatedMonthlySavingsAmount
  }'
# Savings Plans tavsiyelerini çekin
aws ce get-savings-plans-purchase-recommendation 
  --savings-plans-type COMPUTE_SP 
  --term-in-years ONE_YEAR 
  --payment-option NO_UPFRONT 
  --lookback-period-in-days THIRTY_DAYS 
  --output json | jq '.SavingsPlansPurchaseRecommendation.SavingsPlansPurchaseRecommendationDetails[] | {
    hourlyCommitment: .HourlyCommitmentToPurchase,
    estimatedSavings: .EstimatedSavingsAmount,
    estimatedROI: .EstimatedROI
  }'

Burada dikkat etmeniz gereken kritik nokta şu: AWS tavsiyeleri her zaman sizin en yüksek taahhüdü almanızı önerir çünkü daha fazla taahhüt AWS’e yarar. Kendi analizinizi yapın.

Gerçek Dünya Senaryosu 1: E-ticaret Platformu

Diyelim ki bir e-ticaret şirketinde çalışıyorsunuz. Gündüz saatlerinde yoğun trafik var, gece ise ciddi düşüş yaşıyorsunuz. Ama temel altyapı 24/7 çalışıyor.

Tipik konfigürasyon:

  • 10 adet m5.2xlarge instance (web tier, 7/24 çalışıyor)
  • 5 adet c5.4xlarge instance (uygulama tier, 7/24 çalışıyor)
  • 0-15 arasında değişen r5.xlarge instance (yoğun saatlerde auto scaling)

Bu senaryoda doğru yaklaşım şudur:

  • Web ve uygulama tier için Standard RI alın (bunlar değişmeyecek, sabit kapasite)
  • Auto scaling grubundaki dinamik instance’lar için Compute Savings Plans kullanın
  • Hiç taahhüt vermeden çalışan kısmı minimize edin
# Python ile basit bir RI hesaplayıcı scripti
cat << 'EOF' > ri_calculator.py
#!/usr/bin/env python3

on_demand_hourly = 0.384  # m5.2xlarge us-east-1 on-demand fiyatı
ri_1yr_partial_upfront_hourly = 0.226  # 1 yıllık partial upfront
ri_3yr_partial_upfront_hourly = 0.152  # 3 yıllık partial upfront

instance_count = 10
hours_per_month = 730

monthly_od = on_demand_hourly * instance_count * hours_per_month
monthly_1yr_ri = ri_1yr_partial_upfront_hourly * instance_count * hours_per_month
monthly_3yr_ri = ri_3yr_partial_upfront_hourly * instance_count * hours_per_month

print(f"On-Demand Aylık Maliyet: ${monthly_od:.2f}")
print(f"1 Yıllık RI Aylık Maliyet: ${monthly_1yr_ri:.2f} (Tasarruf: ${monthly_od - monthly_1yr_ri:.2f}, %{((monthly_od - monthly_1yr_ri)/monthly_od)*100:.1f})")
print(f"3 Yıllık RI Aylık Maliyet: ${monthly_3yr_ri:.2f} (Tasarruf: ${monthly_od - monthly_3yr_ri:.2f}, %{((monthly_od - monthly_3yr_ri)/monthly_od)*100:.1f})")
EOF

python3 ri_calculator.py

Gerçek Dünya Senaryosu 2: Startup’tan Kurumsal’a Geçiş

Birçok startup başlangıçta her şeyi on-demand kullanır, bu doğru bir yaklaşımdır. Ama belirli bir büyüklüğe geldiğinizde optimizasyon şart olur.

Şöyle bir durum düşünün: 6 ay önce kurduğunuz Kubernetes cluster’ı artık stabil çalışıyor, node grubu boyutu değişmiyor ve aylık EC2 faturanız 15.000 doları aştı. Bu noktada artık on-demand’dan çıkma zamanı gelmiş demektir.

# EKS node gruplarınızın instance tiplerini ve sayılarını listeleyin
aws eks describe-nodegroup 
  --cluster-name prod-cluster 
  --nodegroup-name main-workers 
  --output json | jq '{
    instanceType: .nodegroup.instanceTypes,
    desiredSize: .nodegroup.scalingConfig.desiredSize,
    minSize: .nodegroup.scalingConfig.minSize,
    maxSize: .nodegroup.scalingConfig.maxSize
  }'

Minimum ve desired size arasındaki fark küçükse, minimum kapasite için RI almak mantıklıdır. Maximum ile minimum arasındaki fark için Compute Savings Plans daha uygun olur.

Azure Reserved VM Instances ile Çalışmak

Azure tarafında da durum benzer. Azure Reserved VM Instances, 1 veya 3 yıllık taahhüt karşılığında yüzde 40 ile yüzde 72 arasında tasarruf sağlar.

# Azure CLI ile mevcut rezervasyonları listeleyin
az reservations reservation list 
  --reservation-order-id <your-order-id> 
  --output json | jq '.[] | {
    sku: .sku.name,
    location: .location,
    quantity: .properties.quantity,
    expiryDate: .properties.expiryDateTime,
    utilizationPercentage: .properties.utilizationSummary.trend
  }'
# Azure'da rezervasyon önerilerini çekin
az consumption reservation recommendation list 
  --scope Shared 
  --look-back-period Last30Days 
  --output json | jq '.[] | {
    skuName: .skuName,
    location: .location,
    recommendedQuantity: .recommendedQuantity,
    totalCostWithReservation: .totalCostWithReservation,
    netSavings: .netSavings
  }'

Azure’da dikkat edilmesi gereken önemli nokta, rezervasyonun kapsamını (scope) doğru seçmektir:

  • Single subscription: Sadece belirli bir subscription’daki VM’lere uygulanır
  • Shared: Tüm subscription’larda geçerlidir, büyük organizasyonlar için önerilir
  • Management group: Belirli bir yönetim grubu altındaki tüm subscription’lar için geçerlidir

Reserved Instance Satın Alma Stratejileri

Hepsini bir anda almak yerine kademeli bir yaklaşım benimseyin.

Adım 1: Baseline tespiti

Son 90 günlük kullanım verisine bakın. Hiç kapanmayan, hiç ölçeklenmeyen instance’ları tespit edin. Bunlar kesin RI adaylarıdır.

Adım 2: Ödeme seçeneği değerlendirmesi

  • All Upfront: En yüksek indirim, nakit akışı etkisi var
  • Partial Upfront: Dengeli seçenek, çoğu senaryo için idealdir
  • No Upfront: En düşük indirim ama başlangıç maliyeti yok

Şirketinizin nakit durumuna göre seçim yapın. Eğer bütçeniz varsa All Upfront genellikle en iyi ROI’yi verir. Startup’lar için No Upfront daha makul olabilir.

Adım 3: Portföy yaklaşımı

# Mevcut RI portföyünüzün özetini çekin
aws ec2 describe-reserved-instances 
  --filters Name=state,Values=active 
  --output json | jq '.ReservedInstances[] | {
    instanceType: .InstanceType,
    availabilityZone: .AvailabilityZone,
    instanceCount: .InstanceCount,
    end: .End,
    fixedPrice: .FixedPrice,
    usagePrice: .UsagePrice,
    offeringClass: .OfferingClass
  }'

Bu çıktıyı düzenli olarak kontrol edin. Özellikle bitiş tarihlerine dikkat edin; RI süresi dolduğunda otomatik olarak on-demand fiyatına geçersiniz ve faturanız aniden sıçrar.

Otomatik Uyarı Sistemi Kurmak

RI’ların bitiş tarihini takip etmek için basit bir monitoring scripti yazabilirsiniz:

#!/bin/bash
# ri_expiry_check.sh - RI bitiş tarihi kontrolü

THRESHOLD_DAYS=60
SNS_TOPIC_ARN="arn:aws:sns:us-east-1:123456789:ri-alerts"

# Bitiş tarihi yaklaşan RI'ları bul
expiring_ris=$(aws ec2 describe-reserved-instances 
  --filters Name=state,Values=active 
  --output json | jq --argjson days $THRESHOLD_DAYS '
    .ReservedInstances[] |
    select(
      (.End | strptime("%Y-%m-%dT%H:%M:%S.000Z") | mktime) - now < ($days * 86400)
    ) |
    {
      instanceType: .InstanceType,
      count: .InstanceCount,
      expiryDate: .End
    }
  ')

if [ ! -z "$expiring_ris" ]; then
  message="Dikkat: Asagidaki Reserved Instance'lar $THRESHOLD_DAYS gun icinde sona erecek:n$expiring_ris"
  
  aws sns publish 
    --topic-arn $SNS_TOPIC_ARN 
    --message "$message" 
    --subject "RI Expiry Alert" 
    --output json
    
  echo "Uyari gonderildi: $expiring_ris"
else
  echo "Yakinda sona erecek RI bulunamadi."
fi

Bu scripti bir cron job olarak her gün çalıştırın:

# Crontab'a ekleyin
echo "0 9 * * * /opt/scripts/ri_expiry_check.sh >> /var/log/ri_check.log 2>&1" | crontab -

Savings Plans Optimizasyonu

Savings Plans, özellikle container ve serverless workload’larınız varsa RI’dan çok daha esnek bir çözüm sunar.

# Mevcut Savings Plans kullanım raporunu çekin
aws ce get-savings-plans-utilization 
  --time-period Start=2024-11-01,End=2024-12-01 
  --granularity MONTHLY 
  --output json | jq '{
    totalCommitment: .Total.TotalCommitment,
    usedCommitment: .Total.UsedCommitment,
    unusedCommitment: .Total.UnusedCommitment,
    utilizationPercentage: .Total.UtilizationPercentage,
    netSavings: .Total.NetSavings
  }'

Kullanım oranı yüzde 85’in altına düşüyorsa taahhüdünüz fazla demektir. Savings Plans’ı satmak mümkün değil ama en azından bir sonuçki planlamada daha dikkatli olursunuz.

Savings Plans ve RI’ı birlikte kullanmak:

İdeal strateji şudur: önce Savings Plans uygulanır, kalan kullanım için RI devreye girer, en son olarak on-demand faturalama yapılır. Bunu göz önünde bulundurarak hem RI hem de Savings Plans alıyorsanız çakışmaya dikkat edin, ikisi de aynı workload için indirim yarışına giremez, yani her ikisini de aldığınızda biri diğerinin üzerine binebilir.

Maliyet Takibi için Tag Stratejisi

Reserved Instance ve Savings Plans tasarruflarını anlamlı şekilde raporlayabilmek için iyi bir tag stratejisi şarttır.

# EC2 instance'larına maliyet merkezi tag'i ekleyin
aws ec2 create-tags 
  --resources i-1234567890abcdef0 
  --tags 
    Key=CostCenter,Value=engineering 
    Key=Environment,Value=production 
    Key=Team,Value=platform 
    Key=ReservationStrategy,Value=ri-covered

# Birden fazla instance'a toplu tag eklemek için
instance_ids=$(aws ec2 describe-instances 
  --filters "Name=tag:Environment,Values=production" 
  --query "Reservations[].Instances[].InstanceId" 
  --output text)

aws ec2 create-tags 
  --resources $instance_ids 
  --tags Key=BillingModel,Value=reserved

Tag’leri doğru kullandığınızda, Cost Explorer’da hangi ekibin ne kadar tasarruf sağladığını kolayca görebilirsiniz.

Yaygın Hatalar ve Bunlardan Kaçınma

Hata 1: Yanlış bölge için RI almak

RI’lar varsayılan olarak belirli bir Availability Zone için alınır. Regional RI alırsanız bölge içindeki herhangi bir AZ’de kullanılabilir. Her zaman Regional RI tercih edin, aksi halde AZ’ler arasında dengeleme yaptığınızda tasarrufunuzu kaybedebilirsiniz.

Hata 2: Convertible RI’ı gereksiz yere seçmek

Convertible RI, Standard RI’dan yüzde 10 ile 15 daha az indirim sunar. Instance tipi değiştirme esnekliğine gerçekten ihtiyacınız yoksa Standard RI daha avantajlıdır. Yeni nesil instance’lara geçiş yapacaksanız, RI Marketplace’ten satıp yeni bir tane almak genellikle Convertible RI’a ödenen prim farkından daha mantıklı sonuç verir.

Hata 3: Kullanım verisi yetersizken taahhüt vermek

En az 30 gün, tercihen 90 gün kullanım verisi olmadan büyük miktarda RI satın almayın. Yeni bir uygulama başlattıysanız, önce on-demand veya Spot Instance ile çalışın, kullanım profilini anlayın, sonra RI kararı verin.

Hata 4: 3 yıllık taahhüdü abartmak

3 yıllık RI yüzde 60 ile 70 arasında indirim sunar ama bulut dünyası 3 yılda çok değişir. Yeni instance nesilleri çıkar, mimari değişebilir. 3 yıllık taahhüdü sadece gerçekten sabit ve değişmeyeceğinden emin olduğunuz workload’lar için kullanın. Genel kural olarak portföyünüzün yüzde 20 ile 30’undan fazlasını 3 yıllık taahhütle bağlamayın.

Hata 5: RI’ı sadece hesap sahibinin alması

AWS Organizations kullanıyorsanız, RI ve Savings Plans tüm hesaplarda paylaşılabilir. Eğer her ekip kendi hesabında ayrı ayrı RI alıyorsa, birleştirilerek daha iyi indirim oranları elde edilebilir. Organizations seviyesinde merkezi satın alma yapın.

GCP Committed Use Discounts

Google Cloud Platform’da benzer kavram “Committed Use Discounts” (CUD) olarak geçer. 1 veya 3 yıllık kaynak taahhüdü karşılığında yüzde 37 ile yüzde 55 arasında indirim sunar.

# GCP committed use discounts durumunu kontrol edin
gcloud compute commitments list 
  --filter="status=ACTIVE" 
  --format="json" | jq '.[] | {
    name: .name,
    region: .region,
    plan: .plan,
    endTimestamp: .endTimestamp,
    resources: .resources
  }'

GCP’de CUD’un AWS RI’dan önemli farkı şudur: CUD, kaynak (vCPU, bellek) bazında taahhüt verir, instance tipi bazında değil. Bu da daha esnek bir yapı sunar; 100 vCPU taahhüdünüzü farklı instance tiplerinde kullanabilirsiniz.

Aylık Maliyet Revizyonu Rutini

Tüm bu optimizasyonları bir kez yapıp bırakmak yetmez. Aylık bir rutin oluşturmanız gerekiyor:

  • Her ayın ilk haftasında Cost Explorer’dan RI ve Savings Plans kullanım raporlarını çekin
  • Kullanım oranı yüzde 85’in altına düşen rezervasyonları tespit edin
  • 90 gün içinde sona erecek RI’ları listeleyin ve yenileme kararı verin
  • Yeni instance tipleri veya servisler için mevcut taahhütlerin yeterliliğini değerlendirin
  • Takımlardan bir sonraki çeyreğin büyüme planlarını alın ve buna göre taahhüt miktarını ayarlayın

Bu rutin için basit bir kontrol listesi scripti işinizi kolaylaştırır:

#!/bin/bash
# monthly_cost_review.sh

echo "=== AYLIK MALIYET REVIZYONU ==="
echo "Tarih: $(date)"
echo ""

echo "--- RI Kullanim Orani ---"
aws ce get-reservation-utilization 
  --time-period Start=$(date -d "30 days ago" +%Y-%m-%d),End=$(date +%Y-%m-%d) 
  --granularity MONTHLY 
  --output json | jq '.Total.UtilizationPercentage'

echo ""
echo "--- Savings Plans Kullanim Orani ---"
aws ce get-savings-plans-utilization 
  --time-period Start=$(date -d "30 days ago" +%Y-%m-%d),End=$(date +%Y-%m-%d) 
  --granularity MONTHLY 
  --output json | jq '.Total.UtilizationPercentage'

echo ""
echo "--- On-Demand Kapsam Yuzdesi ---"
aws ce get-reservation-coverage 
  --time-period Start=$(date -d "30 days ago" +%Y-%m-%d),End=$(date +%Y-%m-%d) 
  --granularity MONTHLY 
  --output json | jq '.Total.CoverageHours.CoverageHoursPercentage'

echo ""
echo "--- 90 Gun Icinde Bitecek RI'lar ---"
aws ec2 describe-reserved-instances 
  --filters Name=state,Values=active 
  --output json | jq --argjson threshold $(($(date +%s) + 90*86400)) '
    .ReservedInstances[] |
    select((.End | strptime("%Y-%m-%dT%H:%M:%S.000Z") | mktime) < $threshold) |
    {type: .InstanceType, count: .InstanceCount, end: .End}
  '

Sonuç

Reserved Instance ve Savings Plans, bulut maliyetlerini kontrol altına almanın en etkili yollarından ikisidir. Ama körü körüne taahhüt vermek yerine veri odaklı bir yaklaşım benimsemek kritik önem taşır.

Özet olarak şunları aklınızda tutun:

  • Önce analiz, sonra taahhüt. En az 30 gün kullanım verisi olmadan karar vermeyin.
  • Sabit workload için RI, değişken workload için Savings Plans tercih edin.
  • Kademeli taahhüt yapın. Tüm bütçenizi bir anda bağlamak yerine aylık küçük adımlar atın.
  • Kullanım oranını her ay takip edin. Yüzde 85’in altına düşen rezervasyonlar kırmızı alarm demektir.
  • AWS Organizations kullanıyorsanız merkezi yönetim yapın. Dağınık hesaplarda ayrı ayrı alınan RI’lar verimsizliğe yol açar.
  • RI bitiş tarihlerini takvime ekleyin. On-demand’a döndüğünüz günü farkında olmadan yaşamayın.

Bu stratejileri doğru uyguladığınızda, yılda on binlerce dolar tasarruf sağlamanız hiç de uzak bir hedef değil. Ve bu parayı daha iyi ürün geliştirmeye, daha güçlü altyapıya yatırabilirsiniz.

Bir yanıt yazın

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