2025-12-18
AWS Maliyet Optimizasyonu Araç Seti - Production Workload'lar için Pratik Stratejiler
Native AWS servisleri, otomasyon ve kanıtlanmış implementation pattern'leri kullanarak AWS maliyetlerini %40-70 azaltmaya yönelik kapsamlı bir rehber.
AWS maliyet optimizasyonu, tek bir sihirli araç bulmakla ilgili değil; native AWS servisleri, otomasyon ve organizasyonel pratikleri birleştiren sistematik bir yaklaşım inşa etmekle ilgili. Reaktif fatura analizine odaklanan geleneksel maliyet yönetiminin aksine, modern AWS maliyet optimizasyonu proaktif monitoring, right-sizing, akıllı satın alma stratejileri ve sürekli governance gerektirir.
Production AWS workload’larla çalışırken öğrendim ki organizasyonlar genellikle benzer maliyet sorunlarıyla karşılaşıyor: trafik değişikliğine karşılık gelmeden %20-40 dalgalanan aylık faturalar, haftada sadece 40 saat gerektiğinde 7/24 çalışan development kaynakları ve %10-20 CPU kullanımındaki EC2 instance’ları için %100 kapasite ödemesi. Bu makalede, bu sorunlarla sistematik olarak başa çıkmak için işe yarayan native AWS araçlarını, implementation pattern’lerini ve organizasyonel pratikleri paylaşıyorum. Her bölümde production ortamlarında test edilmiş, gerçek projelerden uyarlanmış örnekler bulacaksın.
Maliyet Zorluğunu Anlamak
Temel problem araç eksikliği değil; AWS mükemmel native maliyet yönetimi yetenekleri sağlıyor. Zorluk, hangi araçları ne zaman kullanacağını bilmek ve etkiyi maksimize ederken riski minimize edecek şekilde doğru sırada uygulamaktır. Önce görünürlük, sonra right-sizing, ardından commitment stratejileri – bu sıra kritik.
Production workload’lar çalıştıran organizasyonlar tipik olarak şu sorunlarla karşılaşıyor. Bu listeyi kendi ortamınıza uyarlayın—her organizasyonun baskın maliyet sürücüleri farklıdır:
- Maliyet öngörülemezliği: İş büyümesine karşılık gelmeden önemli ölçüde değişen aylık faturalar
- Idle kaynak israfı: İş saatleri dışında bütçe yakan non-production kaynaklar
- Over-provisioned instance’lar: Nadiren kullanılan kapasite için ödeme
- Commitment paralizi: Reserved Instances, Savings Plans veya Spot Instances arasında seçim yapma zorluğu
- Attribution eksikliği: Hangi projelerin veya ekiplerin AWS harcamasını yönlendirdiğini track edememe
İyi haber: bunları sistematik olarak ele almak, performans veya güvenilirlikten ödün vermeden maliyetleri %40-70 azaltabilir. Bu rehber, Cost Explorer ve Budgets ile başlayıp Lambda right-sizing, DynamoDB kapasite seçimi ve Savings Plans kararlarına kadar uygulanabilir adımlar sunuyor. Önce görünürlük kur, sonra right-sizing yap, ardından commitment stratejilerine geç—bu sırayı atlamak yanlış boyutlarda satın alma ve gereksiz risklere yol açar. Cost Explorer ve Compute Optimizer gibi araçlar ücretsiz; başlamak için tek ihtiyacın olan düzenli inceleme rutini ve takımınla paylaşılacak net metrikler. Tag’ler tutarlı atanmazsa attribution karışır—Cost Allocation Tags’i ilk gün etkinleştirmek daha sonra retrospektif analiz yapmaktan çok daha kolay. Lambda için provisioned concurrency yalnızca latency-sensitive path’lerde kullanılmalı; aksi halde idle maliyet artar.
Temel: Cost Explorer ve AWS Budgets
Maliyetleri optimize etmeden önce görünürlüğe ihtiyacın var. Cost Explorer ve AWS Budgets, paranın nereye gittiğini anlamak ve anomalileri erken yakalamak için temel sağlıyor. Bu araçlar olmadan right-sizing veya commitment stratejileri kör uçuyor – önce veri, sonra eylem. Cost Explorer’daki dimension’lar (Service, Region, Tag) sayesinde harcama pattern’lerini farklı açılardan inceliyebilir; Budgets ile eşik aşımlarında anında uyarı alırsın. Forecast vs gerçek harcama karşılaştırması sapmaları erken gösterir; aylık review rutini oluşturmak uzun vadede değer katar.
Cost Explorer Derinlemesine
Cost Explorer 12 aylık geçmiş veri ve 12 aya kadar forecasting sunuyor. İşte maliyet trendlerini analiz etmek ve anomalileri tespit etmek için pratik bir implementation:
import boto3
from datetime import datetime, timedelta
ce_client = boto3.client('ce', region_name='us-east-1')
def analyze_cost_trends(months_back=3):
"""
Servisler arasında maliyet trendlerini analiz et ve anomalileri tespit et
Ay bazında %20'den fazla maliyet değişikliği olan servisleri döndürür
"""
end_date = datetime.now().date()
start_date = (datetime.now() - timedelta(days=30 * months_back)).date()
response = ce_client.get_cost_and_usage(
TimePeriod={
'Start': start_date.strftime('%Y-%m-%d'),
'End': end_date.strftime('%Y-%m-%d')
},
Granularity='MONTHLY',
Metrics=['UnblendedCost'],
GroupBy=[
{'Type': 'DIMENSION', 'Key': 'SERVICE'},
]
)
# Sonuçları işle
cost_by_service = {}
for result in response['ResultsByTime']:
period = result['TimePeriod']['Start']
for group in result['Groups']:
service = group['Keys'][0]
cost = float(group['Metrics']['UnblendedCost']['Amount'])
if service not in cost_by_service:
cost_by_service[service] = []
cost_by_service[service].append({
'period': period,
'cost': cost
})
# %20'den fazla maliyet artışı olan servisleri tespit et
trending_services = []
for service, costs in cost_by_service.items():
if len(costs) >= 2:
recent_cost = costs[-1]['cost']
previous_cost = costs[-2]['cost']
if previous_cost > 0:
change_pct = ((recent_cost - previous_cost) / previous_cost) * 100
if abs(change_pct) > 20:
trending_services.append({
'service': service,
'change': change_pct,
'current_cost': recent_cost,
'previous_cost': previous_cost
})
return sorted(trending_services, key=lambda x: abs(x['change']), reverse=True)
Bu script AWS servisleri arasında maliyet anomalilerini tespit ediyor. Pratikte haftalık çalıştırmak, yanlış configure edilmiş Auto Scaling group’ları veya unutulmuş test kaynaklarını önemli maliyet birikmeden yakalamanın işe yaradığını gördüm.
Maliyet Tahsis Boşluklarını Tespit Etme
En gözden kaçan maliyet optimizasyonlarından biri, sadece nelerin track edilmediğini anlamak. Tag’lenmemiş kaynaklar genellikle toplam harcamanın %30-50’sini temsil ediyor:
def analyze_cost_allocation_gaps():
"""
Cost allocation için düzgün tag'lenmemiş maliyetleri tespit et
"""
end_date = datetime.now().date()
start_date = (datetime.now() - timedelta(days=30)).date()
# Tag'lere göre maliyetleri kontrol et
tagged_response = ce_client.get_cost_and_usage(
TimePeriod={
'Start': start_date.strftime('%Y-%m-%d'),
'End': end_date.strftime('%Y-%m-%d')
},
Granularity='MONTHLY',
Metrics=['UnblendedCost'],
GroupBy=[
{'Type': 'TAG', 'Key': 'Project'},
]
)
total_tagged_cost = 0
for result in tagged_response['ResultsByTime']:
for group in result['Groups']:
if group['Keys'][0]: # Project tag'i var
total_tagged_cost += float(group['Metrics']['UnblendedCost']['Amount'])
# Toplam maliyeti al
total_response = ce_client.get_cost_and_usage(
TimePeriod={
'Start': start_date.strftime('%Y-%m-%d'),
'End': end_date.strftime('%Y-%m-%d')
},
Granularity='MONTHLY',
Metrics=['UnblendedCost']
)
total_cost = float(total_response['ResultsByTime'][0]['Total']['UnblendedCost']['Amount'])
untagged_cost = total_cost - total_tagged_cost
untagged_percentage = (untagged_cost / total_cost) * 100
return {
'total_cost': total_cost,
'tagged_cost': total_tagged_cost,
'untagged_cost': untagged_cost,
'untagged_percentage': untagged_percentage
}
Kritik insight: Cost allocation tag’lerini kullanmadan önce Billing Console’da aktif et. Tag’ler sadece aktivasyondan sonraki maliyetleri track ediyor; retroaktif tag’leme yeteneği yok.
Otomatik Eylemlerle AWS Budgets
Budget’lar proaktif maliyet monitoring sağlıyor. İşte birden fazla alert eşiği olan production-ready bir implementation:
import boto3
budgets_client = boto3.client('budgets')
def create_department_budget_with_alerts(
account_id: str,
department: str,
monthly_limit: float
):
"""
Birden fazla alert eşiği ve SNS notification'larıyla budget oluştur
%70 = Info, %90 = Warning, %100 = Critical, Forecasted = Predictive
"""
budget_name = f"{department}-monthly-budget"
budgets_client.create_budget(
AccountId=account_id,
Budget={
'BudgetName': budget_name,
'BudgetLimit': {
'Amount': str(monthly_limit),
'Unit': 'USD'
},
'TimeUnit': 'MONTHLY',
'BudgetType': 'COST',
'CostFilters': {
'TagKeyValue': [f'user:Department${department}']
}
},
NotificationsWithSubscribers=[
# %70 eşiği - Info alert
{
'Notification': {
'NotificationType': 'ACTUAL',
'ComparisonOperator': 'GREATER_THAN',
'Threshold': 70.0,
'ThresholdType': 'PERCENTAGE',
'NotificationState': 'ALARM'
},
'Subscribers': [
{
'SubscriptionType': 'SNS',
'Address': f'arn:aws:sns:us-east-1:{account_id}:budget-alerts-info'
}
]
},
# %90 eşiği - Warning alert
{
'Notification': {
'NotificationType': 'ACTUAL',
'ComparisonOperator': 'GREATER_THAN',
'Threshold': 90.0,
'ThresholdType': 'PERCENTAGE',
'NotificationState': 'ALARM'
},
'Subscribers': [
{
'SubscriptionType': 'SNS',
'Address': f'arn:aws:sns:us-east-1:{account_id}:budget-alerts-warning'
}
]
},
# %100 eşiği - Critical alert
{
'Notification': {
'NotificationType': 'ACTUAL',
'ComparisonOperator': 'GREATER_THAN',
'Threshold': 100.0,
'ThresholdType': 'PERCENTAGE',
'NotificationState': 'ALARM'
},
'Subscribers': [
{
'SubscriptionType': 'SNS',
'Address': f'arn:aws:sns:us-east-1:{account_id}:budget-alerts-critical'
},
{
'SubscriptionType': 'EMAIL',
'Address': f'{department}[email protected]'
}
]
},
# Aşma tahmini - Predictive alert
{
'Notification': {
'NotificationType': 'FORECASTED',
'ComparisonOperator': 'GREATER_THAN',
'Threshold': 100.0,
'ThresholdType': 'PERCENTAGE',
'NotificationState': 'ALARM'
},
'Subscribers': [
{
'SubscriptionType': 'SNS',
'Address': f'arn:aws:sns:us-east-1:{account_id}:budget-forecast-alerts'
}
]
}
]
)
print(f"Budget oluşturuldu: {budget_name} - ${monthly_limit} aylık limit")
Önemli insight: Alert eşikleri günde yaklaşık üç kez tetikleniyor, günlük email’lerden daha hızlı anomaly detection sağlıyor. FORECASTED alert’ler AWS’nin ML tahmin modelini kullanıyor ve tahmin üretmek için en az 5 haftalık geçmiş veri gerektiriyor.
Kaçınılması gereken yaygın hatalar:
- Çok fazla budget oluşturmak alert fatigue’e neden olur; ana maliyet merkezlerine odaklan
- FORECASTED alert’leri 5+ haftalık geçmiş veri gerektirdiğini anlamadan kullanmak
- Tag’lere göre budget filtrelemeden önce cost allocation tag’lerini aktif etmemek
- Tag’lenmemiş kaynak maliyetlerini göz ardı etmek (genellikle toplam harcamanın %30-50’si)
Compute Optimizer ile Right-Sizing
AWS Compute Optimizer, CloudWatch metriklerini analiz etmek ve optimal instance type’ları, Lambda memory konfigürasyonları ve EBS volume’ları önermek için machine learning kullanıyor. Bu tipik olarak düşük implementation riski ile %20-40 maliyet tasarrufu sağlıyor.
Otomatik Right-Sizing Uygulaması
import boto3
from typing import List, Dict
from dataclasses import dataclass
compute_optimizer = boto3.client('compute-optimizer')
ec2_client = boto3.client('ec2')
@dataclass
class RightsizingRecommendation:
instance_id: str
current_type: str
recommended_type: str
current_cost_monthly: float
recommended_cost_monthly: float
savings_monthly: float
cpu_utilization_avg: float
memory_utilization_avg: float
def get_underutilized_instances(
max_cpu_threshold: float = 40.0,
lookback_days: int = 14
) -> List[RightsizingRecommendation]:
"""
Underutilized instance'lar için Compute Optimizer önerilerini getir
Default: 14 gün boyunca ortalama <%40 CPU kullanan instance'lar
"""
recommendations = []
# EC2 instance önerilerini al
paginator = compute_optimizer.get_paginator('get_ec2_instance_recommendations')
for page in paginator.paginate():
for rec in page.get('instanceRecommendations', []):
instance_id = rec['instanceArn'].split('/')[-1]
current_instance_type = rec['currentInstanceType']
# Utilization metriklerini al
cpu_util = next(
(m['value'] for m in rec.get('utilizationMetrics', [])
if m['name'] == 'CPU'),
0.0
)
memory_util = next(
(m['value'] for m in rec.get('utilizationMetrics', [])
if m['name'] == 'MEMORY'),
0.0
)
# Instance underutilized mı kontrol et
if cpu_util < max_cpu_threshold:
# En iyi öneri seçeneğini al
if rec.get('recommendationOptions'):
best_option = rec['recommendationOptions'][0]
# Tasarrufu hesapla
estimated_savings = best_option.get('estimatedMonthlySavings', {}).get('value', 0)
recommendations.append(RightsizingRecommendation(
instance_id=instance_id,
current_type=current_instance_type,
recommended_type=best_option['instanceType'],
current_cost_monthly=estimated_savings,
recommended_cost_monthly=0,
savings_monthly=estimated_savings,
cpu_utilization_avg=cpu_util,
memory_utilization_avg=memory_util
))
# Potansiyel tasarrufa göre sırala (en yüksek önce)
return sorted(recommendations, key=lambda x: x.savings_monthly, reverse=True)
Right-Sizing Önerilerini Uygulama
Öneri uygulamak için instance önce durdurulmalı. İşte dikkatli bir yaklaşım; instance önce durdurulmalı:
def apply_rightsizing_recommendation(
instance_id: str,
new_instance_type: str,
dry_run: bool = True
) -> Dict:
"""
Instance type değiştirerek right-sizing önerisini uygula
Instance'ın önce durdurulması gerekir
"""
try:
response = ec2_client.describe_instances(InstanceIds=[instance_id])
instance_state = response['Reservations'][0]['Instances'][0]['State']['Name']
if instance_state != 'stopped':
return {
'success': False,
'message': f'Instance durdurulmuş olmalı. Mevcut durum: {instance_state}'
}
ec2_client.modify_instance_attribute(
InstanceId=instance_id,
InstanceType={'Value': new_instance_type},
DryRun=dry_run
)
return {
'success': True,
'message': f'{instance_id} başarıyla {new_instance_type} olarak değiştirildi',
'instance_id': instance_id,
'new_type': new_instance_type
}
except Exception as e:
return {
'success': False,
'message': f'Değişiklik başarısız: {str(e)}'
}
İşe yarayan implementation stratejisi: Tüm önerileri bir anda uygulama. Önce development’ta test et, sonra production instance’larının %10’una uygula, bir hafta monitor et, ardından kademeli olarak kalan instance’lara yay.
Lambda Memory Optimizasyonu
Compute Optimizer Lambda fonksiyonlarını da analiz ediyor. İşte Lambda-spesifik öneriler nasıl alınır:
def get_lambda_optimization_recommendations():
"""
Lambda memory konfigürasyon önerilerini al
Performans etkisi olmadan memory azaltılabilen fonksiyonları döndürür
"""
paginator = compute_optimizer.get_paginator('get_lambda_function_recommendations')
recommendations = []
for page in paginator.paginate():
for rec in page.get('lambdaFunctionRecommendations', []):
function_arn = rec['functionArn']
current_memory = rec['currentMemorySize']
if rec.get('recommendationOptions'):
best_option = rec['recommendationOptions'][0]
recommended_memory = best_option['memorySize']
# Sadece öneri mevcut'tan farklıysa dahil et
if recommended_memory != current_memory:
estimated_savings = best_option.get('estimatedMonthlySavings', {})
recommendations.append({
'function_arn': function_arn,
'function_name': function_arn.split(':')[-1],
'current_memory_mb': current_memory,
'recommended_memory_mb': recommended_memory,
'savings_monthly': estimated_savings.get('value', 0),
'savings_currency': estimated_savings.get('currency', 'USD')
})
return sorted(recommendations, key=lambda x: x['savings_monthly'], reverse=True)
Teknik not: Compute Optimizer default olarak son 14 günlük CloudWatch metriklerini analiz ediyor. Aylık kullanım pattern’leri olan production workload’lar için enhanced infrastructure metrics’i aktif et (kaynak başına saat başına 0.25 ekler) ve 93 günlük lookback period’u al.
Compute Optimizer ile yaygın hatalar:
- Maintenance window olmadan iş saatlerinde öneriler uygulama
- Önerilen instance type’ların uyumluluk için test edilmemesi (bazı type’lar tüm özellikleri desteklemez)
- “Under-provisioned” uyarılarını göz ardı etme; maliyet tasarrufu performanstan ödün vermemeli
- Production workload’lar için enhanced metrics aktif etmeme; 14 gün aylık spike’ları kaçırabilir
Commitment Stratejisi: Savings Plans vs Reserved Instances
Reserved Instances, Savings Plans veya on-demand’da kalma arasında seçim yapmak, workload karakteristiklerini anlamayı gerektiriyor. İşte bir karar framework’ü:
Öneri Motoru
AWS’nin commitment önerilerini programatik olarak nasıl alırsın:
import boto3
from typing import List, Dict
from dataclasses import dataclass
ce_client = boto3.client('ce')
@dataclass
class CommitmentRecommendation:
recommendation_type: str # 'RI' veya 'SavingsPlan'
service: str
term: str # '1_YEAR' veya '3_YEAR'
payment_option: str
monthly_commitment: float
estimated_savings: float
estimated_savings_percentage: float
def get_savings_plan_recommendations(
term_years: int = 1,
payment_option: str = 'NO_UPFRONT'
) -> List[CommitmentRecommendation]:
"""
Savings Plans satın alma önerilerini al
Son 30 günlük kullanım pattern'lerine dayalı
"""
response = ce_client.get_savings_plans_purchase_recommendation(
SavingsPlansType='COMPUTE_SP', # veya 'EC2_INSTANCE_SP'
TermInYears=f'{term_years}_YEAR',
PaymentOption=payment_option,
LookbackPeriodInDays='THIRTY_DAYS',
AccountScope='PAYER'
)
recommendations = []
for rec in response.get('SavingsPlansPurchaseRecommendation', {}).get('SavingsPlansPurchaseRecommendationDetails', []):
savings_details = rec.get('SavingsPlansDetails', {})
recommendations.append(CommitmentRecommendation(
recommendation_type='SavingsPlan',
service='Compute',
term=f'{term_years}_YEAR',
payment_option=payment_option,
monthly_commitment=float(rec.get('HourlyCommitmentToPurchase', 0)) * 730,
estimated_savings=float(rec.get('EstimatedMonthlySavingsAmount', 0)),
estimated_savings_percentage=float(rec.get('EstimatedSavingsPercentage', 0))
))
return recommendations
Production kullanımından önemli insights:
- Reserved Instances: %72’ye kadar tasarruf, ama belirli instance family ve region’a kilitli. İhtiyaçlar değişirse RI Marketplace’te satılabilir.
- Compute Savings Plans: %66’ya kadar tasarruf, herhangi bir region veya instance family’de EC2, Fargate ve Lambda’ya uygulanır. Maximum esneklik.
- EC2 Instance Savings Plans: %72’ye kadar tasarruf, instance family ve region içinde esnek. RI’lar ve Compute SP’ler arası orta yol.
- Ödeme seçenekleri: All Upfront (en yüksek indirim), Partial Upfront (dengeli), No Upfront (en düşük indirim ama sermaye commitment’ı yok)
2024 geliştirmesi: AWS artık Savings Plans için kısıtlamalarla 7 günlük iade/değişim penceresi sunuyor (saatlik commitment $100 veya daha az, iadeler aynı takvim ayı içinde olmalı, yılda maksimum 10 iade), uzun vadeli commitment cezası olmadan satın alma hatalarını düzeltmeye izin veriyor.
Commitment’larla yaygın hatalar:
- Baseline yerine peak kullanıma dayalı over-commitment; kullanılmayan commitment’lar sonucu
- Teknoloji evrimini düşünmeden 3 yıllık term’ler seçmek; instance type’lar hızla gelişiyor
- Satın alma sonrası RI/SP kullanımını monitor etmemek; underutilized commitment’lar para israfı
- Net strateji olmadan RI’ları ve SP’leri karıştırmak; coverage gap’leri veya overlap’lere yol açabilir
İşe yarayan strateji: Muhafazakar başla. 1. ayda baseline kullanımın %40’ını kapsla, utilization %95’i aşarsa %60’a artır, uzun vadede %70-80 coverage hedefle. Esneklik ve büyüme için %20-30’u on-demand bırak.
Karşılaştırma Çerçevesi
Değişken stabiliteye sahip workload’lar için karşılaştırma motoru:
def compare_commitment_options(
monthly_spend: float,
workload_stability: str # 'stable', 'variable', 'mixed'
) -> Dict:
"""
Workload karakteristiklerine göre commitment stratejilerini karşılaştır
"""
if workload_stability == 'stable':
return {
'recommendation': 'Reserved Instances',
'reason': 'Stabil, öngörülebilir workload\'lar için en yüksek indirim',
'expected_savings': monthly_spend * 0.75,
'flexibility': 'Düşük - instance family ve region\'a kilitli',
'best_for': 'Production veritabanları, sürekli çalışan servisler'
}
elif workload_stability == 'variable':
return {
'recommendation': 'Compute Savings Plans',
'reason': 'Instance family, region ve compute servisleri arasında esneklik',
'expected_savings': monthly_spend * 0.66,
'flexibility': 'Yüksek - EC2, Fargate, Lambda\'ya uygulanır',
'best_for': 'Çok servisli mimariler, evrimleşen workload\'lar'
}
else:
stable_portion = monthly_spend * 0.6
variable_portion = monthly_spend * 0.4
return {
'recommendation': 'Hibrit Strateji',
'reason': 'Baseline için RI, esneklik için Savings Plans birleştir',
'breakdown': {
'reserved_instances': {
'monthly_commitment': stable_portion,
'savings': stable_portion * 0.75
},
'savings_plans': {
'monthly_commitment': variable_portion,
'savings': variable_portion * 0.66
}
},
'expected_total_savings': (stable_portion * 0.75) + (variable_portion * 0.66),
'flexibility': 'Dengeli - her iki senaryo için optimize'
}
Batch Workload’lar için Spot Instances
Spot Instances %70-90 maliyet tasarrufu sunuyor ama interruption-resilient mimari gerektiriyor. İşte ne zaman ve nasıl etkili kullanılır:
Çeşitlendirme ile Spot Fleet
Spot Instance dayanıklılığının anahtarı instance type’ları ve availability zone’ları arasında diversification:
import boto3
from typing import List, Dict
ec2_client = boto3.client('ec2')
autoscaling_client = boto3.client('autoscaling')
def create_diversified_spot_fleet(
target_capacity: int,
instance_types: List[str],
subnets: List[str],
user_data_script: str
) -> str:
"""
Diversified Spot instance'larla EC2 Auto Scaling group oluştur
Interruption'ları minimize etmek için capacity-optimized allocation strategy kullanır
"""
# Launch template konfigürasyonu
launch_template_overrides = []
for instance_type in instance_types:
for subnet in subnets:
launch_template_overrides.append({
'InstanceType': instance_type,
'SubnetId': subnet,
'WeightedCapacity': 1.0
})
# Mixed instances policy ile Auto Scaling group oluştur
asg_config = {
'AutoScalingGroupName': 'spot-optimized-asg',
'MinSize': target_capacity,
'MaxSize': target_capacity * 2,
'DesiredCapacity': target_capacity,
'VPCZoneIdentifier': ','.join(subnets),
'MixedInstancesPolicy': {
'InstancesDistribution': {
'OnDemandBaseCapacity': 0, # Tüm Spot instance'lar
'OnDemandPercentageAboveBaseCapacity': 0,
'SpotAllocationStrategy': 'capacity-optimized',
'SpotInstancePools': len(instance_types) * len(subnets)
},
'LaunchTemplate': {
'LaunchTemplateSpecification': {
'LaunchTemplateName': 'spot-fleet-template',
'Version': '$Latest'
},
'Overrides': launch_template_overrides
}
},
'Tags': [
{
'Key': 'CostOptimization',
'Value': 'SpotInstances',
'PropagateAtLaunch': True
}
]
}
response = autoscaling_client.create_auto_scaling_group(**asg_config)
return asg_config['AutoScalingGroupName']
Kritik insight: Capacity-optimized allocation strategy kullan ve 10+ instance type ile 3+ availability zone arasında diversify et. Bu, single-type Spot fleet’lere kıyasla interruption rate’lerini %90’a kadar azaltıyor.
Kesinti Yönetimi
Spot instance’lar sonlandırmadan önce EventBridge üzerinden 2 dakika uyarı verir. Graceful shutdown için Lambda fonksiyonu:
# Spot kesintisi için Lambda fonksiyonu
def lambda_handler(event, context):
'''
EC2 Spot Instance kesinti uyarılarını işle (2 dakika bildirim)
Strateji: Task'ları boşalt ve işi kuyruğa geri gönder
'''
detail = event.get('detail', {})
instance_id = detail.get('instance-id')
instance_action = detail.get('instance-action')
if not instance_id:
return {'statusCode': 400, 'body': 'Olayda instance ID yok'}
# Instance detaylarını ve tag'lerini al
response = ec2_client.describe_instances(InstanceIds=[instance_id])
instance = response['Reservations'][0]['Instances'][0]
task_queue_url = get_tag_value(instance.get('Tags', []), 'TaskQueueUrl')
if task_queue_url:
sqs_client.send_message(
QueueUrl=task_queue_url,
MessageBody=json.dumps({
'action': 'drain_instance',
'instance_id': instance_id,
'interruption_time': detail.get('time')
})
)
return {'statusCode': 200, 'body': f'{instance_id} kesintisi işlendi'}
Uzun Süren İşler için Checkpoint
2 saatten uzun job’lar için checkpoint ile kesinti sonrası kaldığı yerden devam et:
def save_checkpoint(state, bucket, prefix='checkpoints'):
"""Job checkpoint'ini S3'e kaydet - Spot kesintisi sonrası kurtarma için"""
checkpoint_key = f"{prefix}/{state.job_id}/checkpoint-{state.current_step}.pkl"
s3_client.put_object(
Bucket=bucket,
Key=checkpoint_key,
Body=pickle.dumps(state),
ServerSideEncryption='AES256'
)
def restore_checkpoint(job_id, bucket, prefix='checkpoints'):
"""Kesintiye uğrayan job için son checkpoint'i geri yükle"""
response = s3_client.list_objects_v2(Bucket=bucket, Prefix=f"{prefix}/{job_id}/")
latest = sorted(response['Contents'], key=lambda x: x['LastModified'], reverse=True)[0]
obj = s3_client.get_object(Bucket=bucket, Key=latest['Key'])
return pickle.loads(obj['Body'].read())
Production’dan en iyi pratikler: 30 dakikadan uzun job’lar için 5-10 dakikada bir checkpoint al.
S3 Depolama Optimizasyonu
S3 depolama maliyetleri Intelligent-Tiering ve lifecycle policy’leri ile %40-95 azaltılabilir. Etkili implementation:
def create_intelligent_lifecycle_policy(
bucket_name: str,
prefix: str = '',
enable_deep_archive_tier: bool = True
) -> Dict:
"""
Intelligent-Tiering'e geçiş ve opsiyonel deep archive tier ile
S3 lifecycle policy oluştur
"""
lifecycle_rules = [
{
'ID': 'transition-to-intelligent-tiering',
'Filter': {'Prefix': prefix},
'Status': 'Enabled',
'Transitions': [{'Days': 0, 'StorageClass': 'INTELLIGENT_TIERING'}]
},
{
'ID': 'cleanup-incomplete-multipart-uploads',
'Filter': {'Prefix': prefix},
'Status': 'Enabled',
'AbortIncompleteMultipartUpload': {'DaysAfterInitiation': 7}
},
{
'ID': 'expire-old-versions',
'Filter': {'Prefix': prefix},
'Status': 'Enabled',
'NoncurrentVersionExpiration': {'NoncurrentDays': 90}
}
]
s3_client.put_bucket_lifecycle_configuration(
Bucket=bucket_name,
LifecycleConfiguration={'Rules': lifecycle_rules}
)
if enable_deep_archive_tier:
s3_client.put_bucket_intelligent_tiering_configuration(
Bucket=bucket_name,
Id='deep-archive-config',
IntelligentTieringConfiguration={
'Id': 'deep-archive-config',
'Status': 'Enabled',
'Tierings': [
{'Days': 90, 'AccessTier': 'ARCHIVE_ACCESS'},
{'Days': 180, 'AccessTier': 'DEEP_ARCHIVE_ACCESS'}
]
}
)
return {'bucket': bucket_name, 'rules_applied': len(lifecycle_rules)}
S3 Intelligent-Tiering detayları: Dört otomatik erişim katmanı. Archive Instant Access ile %68’e kadar, Deep Archive ile %95’e kadar tasarruf. 128KB’dan küçük objeler monitoring ücreti nedeniyle uygun değil.
Lambda Maliyet Optimizasyonu
Lambda maliyeti üç bileşenden oluşur: request, duration (GB-saniye) ve opsiyonel provisioned concurrency. Her birini nasıl optimize edeceğin:
Power Tuning ile Memory Optimizasyonu
AWS Lambda Power Tuning (açık kaynak) veri odaklı memory optimizasyonu sağlıyor:
def run_lambda_power_tuning(
function_name: str,
power_values: List[int] = [128, 256, 512, 1024, 1536, 2048, 3008],
num_invocations: int = 10,
strategy: str = 'balanced' # 'cost', 'speed' veya 'balanced'
) -> Dict:
"""
Optimal memory konfigürasyonunu bulmak için AWS Lambda Power Tuning çalıştır
GitHub: alexcasalboni/aws-lambda-power-tuning
"""
input_payload = {
'lambdaARN': f'arn:aws:lambda:us-east-1:123456789012:function:{function_name}',
'powerValues': power_values,
'num': num_invocations,
'payload': {},
'parallelInvocation': True,
'strategy': strategy
}
response = stepfunctions_client.start_execution(
stateMachineArn='arn:aws:states:us-east-1:123456789012:stateMachine:lambda-power-tuner',
input=json.dumps(input_payload)
)
# Sonuçları bekle ve döndür
return {'recommended_memory': output.get('power'), 'optimization_summary': output}
Provisioned Concurrency Maliyet Analizi
Provisioned concurrency cold start’ı ortadan kaldırıyor ama her GB için ~$13/ay always-warm kapasite maliyeti var. Ne zaman mantıklı:
def calculate_lambda_costs(config: LambdaCostBreakdown) -> Dict:
"""
Provisioned concurrency ile ve olmadan Lambda maliyetlerini hesapla
Provisioned concurrency'nin maliyet-etkin olup olmadığını belirlemeye yardımcı olur
"""
price_per_request = 0.20 / 1_000_000
price_per_gb_second = 0.0000166667
provisioned_price_per_gb_hour = 0.0000041667
memory_gb = config.memory_mb / 1024
duration_seconds = config.avg_duration_ms / 1000
request_cost = config.invocations_monthly * price_per_request
compute_cost = config.invocations_monthly * duration_seconds * memory_gb * price_per_gb_second
total_on_demand = request_cost + compute_cost
provisioned_cost = 0
if config.provisioned_concurrency:
provisioned_cost = (config.provisioned_concurrency * memory_gb * 730 *
provisioned_price_per_gb_hour)
total_with_provisioned = request_cost + compute_cost + provisioned_cost
return {
'on_demand_cost_monthly': round(total_on_demand, 2),
'provisioned_cost_monthly': round(total_with_provisioned, 2),
'recommendation': 'Provisioned concurrency kullan' if total_with_provisioned < total_on_demand * 1.5 else 'On-demand\'da kal'
}
Lambda optimizasyon notları: Memory allocation CPU ve network’ü de belirliyor. Sık kullanılan tatlı nokta 1024-1536MB. Provisioned concurrency sadece kesin latency gereksinimli user-facing API’lerde kullan.
Maliyet Tahsisi ve Etiketleme
Kapsamlı tagging ekipler, projeler ve environment’lar arasında maliyet attribution sağlar. Production-ready yaklaşım:
def create_tagging_compliance_rule():
"""
Tag'lenmemiş kaynakları tespit eden AWS Config kuralı oluştur
Environment, Project, CostCenter tag'lerini zorunlu kılar
"""
config_client.put_config_rule(ConfigRule={
'ConfigRuleName': 'required-tags-compliance',
'Description': 'Kaynakların gerekli cost allocation tag\'lerine sahip olduğunu kontrol et',
'Source': {'Owner': 'AWS', 'SourceIdentifier': 'REQUIRED_TAGS'},
'InputParameters': '{"tag1Key":"Environment","tag2Key":"Project","tag3Key":"CostCenter"}',
'Scope': {
'ComplianceResourceTypes': [
'AWS::EC2::Instance', 'AWS::RDS::DBInstance', 'AWS::S3::Bucket',
'AWS::Lambda::Function', 'AWS::DynamoDB::Table'
]
}
})
return {'rule_name': 'required-tags-compliance'}
Maliyet Tahsis Raporlaması
Tag’lere göre gruplanmış aylık maliyet raporları chargeback/showback için:
def generate_cost_allocation_report(
month: str,
group_by_tags: List[str] = ['Project', 'Environment', 'CostCenter']
) -> Dict:
"""
Tag'lere göre gruplanmış maliyet tahsis raporu oluştur
Dikkat gerektiren tag'lenmemiş maliyetleri tespit eder
"""
start_date = datetime.strptime(f'{month}-01', '%Y-%m-%d')
if start_date.month == 12:
end_date = start_date.replace(year=start_date.year + 1, month=1, day=1)
else:
end_date = start_date.replace(month=start_date.month + 1, day=1)
end_date = end_date - timedelta(days=1)
cost_by_tags = {}
for tag_key in group_by_tags:
response = ce_client.get_cost_and_usage(
TimePeriod={'Start': start_date.strftime('%Y-%m-%d'), 'End': end_date.strftime('%Y-%m-%d')},
Granularity='MONTHLY',
Metrics=['UnblendedCost'],
GroupBy=[{'Type': 'TAG', 'Key': tag_key}]
)
tag_costs = {}
for result in response['ResultsByTime']:
for group in result['Groups']:
tag_value = group['Keys'][0].split('$')[1] if '$' in group['Keys'][0] else 'Untagged'
cost_by_tags[tag_key] = tag_costs
total_response = ce_client.get_cost_and_usage(
TimePeriod={'Start': start_date.strftime('%Y-%m-%d'), 'End': end_date.strftime('%Y-%m-%d')},
Granularity='MONTHLY', Metrics=['UnblendedCost'])
total_cost = float(total_response['ResultsByTime'][0]['Total']['UnblendedCost']['Amount'])
return {'month': month, 'total_cost': round(total_cost, 2), 'breakdown_by_tags': cost_by_tags}
Tagging en iyi pratikleri: Gerekli tag’ler: Environment, Project, CostCenter, Owner. Cost allocation tag’lerini Billing Console’da kullanmadan önce aktif et. Hedef: <%10 tag’lenmemiş maliyet.
Optimizasyon Teknikleri Karşılaştırması
| Teknik | Tasarruf | Uygulama Çabası | Risk | En İyi Kullanım |
|---|---|---|---|---|
| Right-Sizing (Compute Optimizer) | %20-40 | Düşük | Düşük | Over-provisioned instance’lar |
| Savings Plans | %66’ya kadar | Düşük | Orta | Öngörülebilir baseline |
| Reserved Instances | %72’ye kadar | Düşük | Orta | Stabil workload’lar |
| Spot Instances | %70-90 | Orta | Orta | Fault-tolerant workload’lar |
| Lambda memory optimizasyonu | %20-50 | Düşük | Düşük | Lambda-ağır mimariler |
| S3 Intelligent-Tiering | %40-95 | Düşük | Düşük | Büyük depolama, karışık erişim |
| Aurora Serverless v2 | %30-70 | Orta | Düşük | Değişken veritabanı workload’ları |
| Instance scheduling | %70 | Orta | Düşük | Non-production environment’lar |
Önemli Çıkarımlar
Engineering Ekipleri için:
-
Maliyet optimizasyonu sürekli, tek seferlik değil: Compute Optimizer önerilerini aylık gözden geçir, utilization’a göre Savings Plans’i üç ayda bir ayarla, kullanılmayan kaynakları haftalık temizle.
-
Right-sizing en hızlı ROI sağlar: Compute Optimizer düşük implementation riski ile %20-40 tasarruf fırsatları tespit ediyor. Güven oluşturmak için non-production environment’larla başla.
-
Tag’leme maliyet sorumluluğunu sağlar: Tag’leri kaynak oluşturma sırasında zorla (retroaktif olarak değil). Gerekli tag’ler: Environment, Project, CostCenter, Owner. <%10 tag’lenmemiş maliyet hedefle.
Platform/FinOps Ekipleri için:
-
Önce maliyet görünürlüğü oluştur: Geçmiş analiz için Cost Explorer, proaktif alerting için Budgets, olağandışı harcama pattern’leri için Cost Anomaly Detection.
-
Governance’ı erken implement et: AWS Organizations üzerinden tag policy’leri, compliance monitoring için AWS Config, harcama limitleri için Service Control Policy’ler.
-
Commitment’ları ve esnekliği dengele: Baseline’ın %60-70’ini Savings Plans/RI’larla kapsla, büyüme için %30-40’ı on-demand bırak. 1 yıllık term’lerle başla (3 yıllıktan daha az risk).
Teknik Karar Vericiler için:
-
Hızlı kazanımlar vs uzun vadeli strateji: 1. ay %20-30 tasarruf (idle kaynaklar, S3 lifecycle, budget’lar), 2-3. aylar %20-30 ekler (rightsizing, commitment’lar), 4+ ay %5-10 sürekli ekler (continuous improvement).
-
Maliyet optimizasyon ROI’si: Aylık 480,000 tasarruf. Platform engineer zaman yatırımı: ayda ~40 saat. ROI: yatırılan zamana 60x+ dönüş.
-
Kültürel değişim kritik: Maliyeti performans ve güvenilirlikle birlikte bir KPI yap. Mimari incelemelerinde maliyet etkisini dahil et. Ekiplerle optimizasyon kazanımlarını kutla.
Burada kapsanan araçlar ve teknikler AWS maliyet optimizasyonuna sistematik bir yaklaşım sağlıyor. Hızlı kazanımlarla başla, görünürlük oluştur, ardından kademeli olarak stratejik optimizasyonlar implement et. Anahtar, maliyet optimizasyonunu tek seferlik bir proje değil, sürekli bir engineering pratiği olarak ele almak. Ekibinin kültürüne maliyet bilincini dahil etmek—mimari kararlarda maliyet boyutunu sorgulama alışkanlığı—uzun vadede tek tek optimizasyonlardan daha fazla etki yaratır.
Uygulama sırası: İlk ay idle kaynakları kapat, S3 lifecycle policy’leri aktif et, budget alarmları kur. İkinci üç ayda Compute Optimizer önerilerini uygula, Savings Plans’e başla. Sonraki aylarda sürekli iyileştirme: aylık cost review, yeni workload’lar için right-sizing checklist.
Kaynaklar
- AWS Cost Explorer - Maliyet verilerini analiz etmek ve trendleri görselleştirmek için temel araç
- AWS Budgets - Bütçe eşikleri ve proaktif uyarılar
- AWS Compute Optimizer - EC2, Lambda ve EBS için otomatik öneriler
- Savings Plans - Esnek commitment seçenekleri ve tasarruf modelleri
- Spot Instances - Kesintiye dayanıklı iş yükleri için maliyet optimizasyonu
- S3 Intelligent-Tiering - Erişim paternine göre otomatik depolama geçişleri
- FinOps Foundation - Bulut maliyet yönetimi pratikleri ve topluluk kaynakları
İlgili yazılar
Global uygulamalar için AWS edge computing çözümlerini seçme ve uygulama üzerine pratik örnekler ve maliyet optimizasyonu stratejileri içeren kapsamlı teknik rehber.
Amazon Cognito'nun gelişmiş özellikleri üzerine kapsamlı teknik kılavuz: özel authentication akışları, federation pattern'leri, multi-tenancy mimarileri, migration stratejileri ve production-grade güvenlik implementasyonu.
AWS Secrets Manager ve Systems Manager Parameter Store'u karşılaştıran kapsamlı teknik rehber - hangi servisi ne zaman kullanmalı ve gerçek dünya implementation pattern'leri.
Token-based pricing, production LLM uygulamaları için benzersiz maliyet zorlukları yaratır. Prompt caching, model routing ve token budget'ları ile kaliteden ödün vermeden maliyetleri %60-80 azaltmak için sistematik optimizasyon stratejilerini öğren.
Aurora mimarisi, maliyet analizi ve RDS'e göre ne zaman seçilmesi gerektiğine dair kapsamlı rehber. Migration stratejileri, performans özellikleri ve gerçek dünya karar çerçeveleri içerir.