AWS EC2 Auto Scaling Kurulumu ve Yapılandırması
Üretim ortamında aniden artan trafik yüzünden sunucunun çöktüğünü yaşadıysanız, Auto Scaling’in ne kadar hayat kurtarıcı olduğunu çok iyi anlarsınız. AWS EC2 Auto Scaling, uygulamanızın yükünü otomatik olarak izleyip kapasiteyi dinamik biçimde ayarlayan bir mekanizmadır. Doğru kurulduğunda hem maliyetlerinizi optimize eder hem de yüksek erişilebilirliği garantiler. Bu yazıda sıfırdan başlayıp production’a hazır bir Auto Scaling yapısı kuracağız.
Auto Scaling Nedir ve Neden Kullanmalısınız
Auto Scaling temelde üç soruyu çözer: Ne zaman ölçekleneceğim, nasıl ölçekleneceğim ve hangi sınırlar içinde kalacağım. Geleneksel yaklaşımda bir sysadmin olarak “şu an kaç sunucu yeterli?” sorusuna zirve trafiğine göre yanıt verirsiniz. Bu da çoğu zaman %70 boşta duran, para yakan sunuculara yol açar.
Auto Scaling ile bu denklemi tamamen değiştiriyorsunuz. CPU %80’e çıktığında yeni instance açılıyor, trafik düştüğünde kapatılıyor. Gece 3’te kimse alışveriş yapmıyorken 20 sunucu döndürmek yerine 2 sunucuyla idare ediyorsunuz.
Temel bileşenler şunlardır:
- Launch Template: Hangi AMI, instance tipi, security group, user data kullanılacağını tanımlar
- Auto Scaling Group (ASG): Kaç instance çalışacağını, hangi AZ’lerde dağıtılacağını belirler
- Scaling Policy: Ölçekleme kararlarını tetikleyen kurallar
- CloudWatch Alarms: Metrikleri izleyip policy’leri tetikler
Ön Hazırlık: IAM ve Ağ Yapısı
Auto Scaling kurulumuna geçmeden önce temel altyapının hazır olması gerekiyor. IAM rolü ve VPC yapısını AWS CLI üzerinden ayarlayalım.
Önce AWS CLI’ın doğru yapılandırıldığından emin olun:
aws configure list
aws sts get-caller-identity
Çıktıda hesap ID’niz ve kullanıcı bilgileriniz görünüyorsa hazırsınız demektir.
EC2 instance’larınızın kullanacağı IAM rolünü oluşturalım:
# Trust policy dosyası oluştur
cat > ec2-trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
# IAM rolü oluştur
aws iam create-role
--role-name EC2AutoScalingRole
--assume-role-policy-document file://ec2-trust-policy.json
# SSM ve CloudWatch politikalarını ekle
aws iam attach-role-policy
--role-name EC2AutoScalingRole
--policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
aws iam attach-role-policy
--role-name EC2AutoScalingRole
--policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
# Instance profile oluştur
aws iam create-instance-profile
--instance-profile-name EC2AutoScalingProfile
aws iam add-role-to-instance-profile
--instance-profile-name EC2AutoScalingProfile
--role-name EC2AutoScalingRole
Security group’u da bu aşamada oluşturalım. VPC ID’nizi değiştirmeyi unutmayın:
# Security group oluştur
SG_ID=$(aws ec2 create-security-group
--group-name asg-webserver-sg
--description "Auto Scaling web sunucusu security group"
--vpc-id vpc-XXXXXXXXX
--query 'GroupId'
--output text)
echo "Security Group ID: $SG_ID"
# HTTP ve HTTPS izinleri ekle
aws ec2 authorize-security-group-ingress
--group-id $SG_ID
--protocol tcp
--port 80
--cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress
--group-id $SG_ID
--protocol tcp
--port 443
--cidr 0.0.0.0/0
# SSH erişimi (sadece kendi IP'niz için)
MY_IP=$(curl -s https://checkip.amazonaws.com)
aws ec2 authorize-security-group-ingress
--group-id $SG_ID
--protocol tcp
--port 22
--cidr ${MY_IP}/32
Launch Template Oluşturma
Launch Template, Auto Scaling Group’un yeni instance açarken kullanacağı şablondur. Eski yöntem olan Launch Configuration’ın aksine versiyonlama destekler ve değişiklik yapıldığında var olan instance’lar etkilenmez.
User data script’i hazırlayalım. Bu script her yeni instance açıldığında çalışacak:
cat > userdata.sh << 'USERDATA'
#!/bin/bash
set -e
# Sistem güncellemeleri
dnf update -y
# Nginx kur
dnf install -y nginx
# CloudWatch Agent kur
dnf install -y amazon-cloudwatch-agent
# Nginx'i başlat ve aktifleştir
systemctl enable nginx
systemctl start nginx
# Basit sağlık kontrolü endpoint'i
cat > /usr/share/nginx/html/health << 'EOF'
OK
EOF
# Instance metadata'dan hostname al ve ana sayfaya yaz
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
cat > /usr/share/nginx/html/index.html << EOF
<html>
<body>
<h1>Instance: ${INSTANCE_ID}</h1>
<p>AZ: ${AZ}</p>
</body>
</html>
EOF
# CloudWatch Agent konfigürasyonu
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl
-a fetch-config
-m ec2
-s
-c ssm:/cloudwatch-agent/config
USERDATA
# Base64 encode et
USERDATA_B64=$(base64 -w 0 userdata.sh)
Şimdi Launch Template’i oluşturalım:
aws ec2 create-launch-template
--launch-template-name "webserver-lt"
--version-description "v1 - Nginx web sunucusu"
--launch-template-data "{
"ImageId": "ami-0c55b159cbfafe1f0",
"InstanceType": "t3.medium",
"KeyName": "my-keypair",
"SecurityGroupIds": ["$SG_ID"],
"IamInstanceProfile": {
"Name": "EC2AutoScalingProfile"
},
"UserData": "$USERDATA_B64",
"Monitoring": {
"Enabled": true
},
"TagSpecifications": [
{
"ResourceType": "instance",
"Tags": [
{"Key": "Name", "Value": "webserver-asg"},
{"Key": "Environment", "Value": "production"},
{"Key": "ManagedBy", "Value": "AutoScaling"}
]
}
]
}"
Launch Template ID’sini alalım:
LT_ID=$(aws ec2 describe-launch-templates
--launch-template-names "webserver-lt"
--query 'LaunchTemplates[0].LaunchTemplateId'
--output text)
echo "Launch Template ID: $LT_ID"
Application Load Balancer Kurulumu
Auto Scaling ile birlikte mutlaka bir Load Balancer kullanmanız gerekir. ALB olmadan yeni açılan instance’lara trafik yönlendiremezsiniz.
# Subnet ID'lerinizi önceden belirleyin (en az 2 farklı AZ)
SUBNET_1="subnet-XXXXXXX"
SUBNET_2="subnet-YYYYYYY"
VPC_ID="vpc-XXXXXXXXX"
# ALB için ayrı security group
ALB_SG_ID=$(aws ec2 create-security-group
--group-name asg-alb-sg
--description "ALB security group"
--vpc-id $VPC_ID
--query 'GroupId'
--output text)
aws ec2 authorize-security-group-ingress
--group-id $ALB_SG_ID
--protocol tcp
--port 80
--cidr 0.0.0.0/0
# ALB oluştur
ALB_ARN=$(aws elbv2 create-load-balancer
--name webserver-alb
--subnets $SUBNET_1 $SUBNET_2
--security-groups $ALB_SG_ID
--query 'LoadBalancers[0].LoadBalancerArn'
--output text)
echo "ALB ARN: $ALB_ARN"
# Target Group oluştur
TG_ARN=$(aws elbv2 create-target-group
--name webserver-tg
--protocol HTTP
--port 80
--vpc-id $VPC_ID
--health-check-path /health
--health-check-interval-seconds 30
--healthy-threshold-count 2
--unhealthy-threshold-count 3
--query 'TargetGroups[0].TargetGroupArn'
--output text)
echo "Target Group ARN: $TG_ARN"
# Listener oluştur
aws elbv2 create-listener
--load-balancer-arn $ALB_ARN
--protocol HTTP
--port 80
--default-actions Type=forward,TargetGroupArn=$TG_ARN
Auto Scaling Group Oluşturma
Artık tüm bileşenler hazır. ASG’yi oluşturalım:
aws autoscaling create-auto-scaling-group
--auto-scaling-group-name "webserver-asg"
--launch-template "LaunchTemplateId=$LT_ID,Version=1"
--min-size 2
--max-size 10
--desired-capacity 2
--target-group-arns $TG_ARN
--vpc-zone-identifier "$SUBNET_1,$SUBNET_2"
--health-check-type ELB
--health-check-grace-period 300
--default-cooldown 300
--tags
"Key=Name,Value=webserver-asg,PropagateAtLaunch=true"
"Key=Environment,Value=production,PropagateAtLaunch=true"
Parametre açıklamaları:
- min-size: ASG’nin hiçbir zaman bu değerin altına düşmeyeceği instance sayısı
- max-size: Ölçekleme sırasında geçilemeyecek üst sınır
- desired-capacity: Şu an çalışması istenen instance sayısı
- health-check-grace-period: Yeni instance’a sağlık kontrolü başlamadan önce verilen süre (saniye)
- default-cooldown: Bir ölçekleme işleminden sonra yeni ölçekleme için bekleme süresi
Scaling Policy Tanımları
Auto Scaling’in gerçek gücü burada devreye giriyor. Üç farklı policy tipi var ve her birinin kullanım senaryosu farklı.
Target Tracking Policy (Önerilen)
En basit ve en etkili yöntem. “CPU’yu %60’ta tut” dersiniz, AWS gerisini halleder:
aws autoscaling put-scaling-policy
--auto-scaling-group-name "webserver-asg"
--policy-name "cpu-target-tracking"
--policy-type TargetTrackingScaling
--target-tracking-configuration '{
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ASGAverageCPUUtilization"
},
"TargetValue": 60.0,
"ScaleInCooldown": 300,
"ScaleOutCooldown": 60
}'
ALB request sayısına göre ölçekleme yapmak için:
aws autoscaling put-scaling-policy
--auto-scaling-group-name "webserver-asg"
--policy-name "alb-request-tracking"
--policy-type TargetTrackingScaling
--target-tracking-configuration "{
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ALBRequestCountPerTarget",
"ResourceLabel": "$(echo $ALB_ARN | cut -d'/' -f2-)/targetgroup/$(echo $TG_ARN | cut -d'/' -f2-)"
},
"TargetValue": 1000.0,
"ScaleInCooldown": 300,
"ScaleOutCooldown": 60
}"
Scheduled Scaling
Her gün saat 08:00’de iş saatlerine hazırlanmak, 20:00’de küçülmek isteyebilirsiniz:
# Sabah ölçek büyüt (UTC 05:00 = TR 08:00)
aws autoscaling put-scheduled-update-group-action
--auto-scaling-group-name "webserver-asg"
--scheduled-action-name "business-hours-scale-out"
--recurrence "0 5 * * 1-5"
--min-size 4
--max-size 10
--desired-capacity 4
# Akşam ölçek küçült (UTC 17:00 = TR 20:00)
aws autoscaling put-scheduled-update-group-action
--auto-scaling-group-name "webserver-asg"
--scheduled-action-name "off-hours-scale-in"
--recurrence "0 17 * * 1-5"
--min-size 2
--max-size 10
--desired-capacity 2
CloudWatch Alarmları ve Bildirimler
ASG’nin durumunu izlemek için CloudWatch alarmları kuralım:
# SNS topic oluştur (e-posta bildirimleri için)
SNS_ARN=$(aws sns create-topic
--name asg-alerts
--query 'TopicArn'
--output text)
aws sns subscribe
--topic-arn $SNS_ARN
--protocol email
--notification-endpoint [email protected]
# ASG bildirimlerini yapılandır
aws autoscaling put-notification-configuration
--auto-scaling-group-name "webserver-asg"
--topic-arn $SNS_ARN
--notification-types
autoscaling:EC2_INSTANCE_LAUNCH
autoscaling:EC2_INSTANCE_TERMINATE
autoscaling:EC2_INSTANCE_LAUNCH_ERROR
autoscaling:EC2_INSTANCE_TERMINATE_ERROR
# Yüksek CPU alarmı
aws cloudwatch put-metric-alarm
--alarm-name "asg-high-cpu"
--alarm-description "ASG ortalama CPU %80 ustunde"
--metric-name CPUUtilization
--namespace AWS/EC2
--dimensions Name=AutoScalingGroupName,Value=webserver-asg
--statistic Average
--period 300
--threshold 80
--comparison-operator GreaterThanThreshold
--evaluation-periods 2
--alarm-actions $SNS_ARN
--treat-missing-data notBreaching
Instance Refresh ile Güvenli Güncelleme
Yeni AMI veya Launch Template değişikliği olduğunda mevcut instance’ları sıfırdan açılan yenileriyle değiştirmeniz gerekir. Instance Refresh bu işi kesintisiz yapar:
# Önce Launch Template'in yeni versiyonunu oluştur
aws ec2 create-launch-template-version
--launch-template-id $LT_ID
--version-description "v2 - Guncel AMI"
--source-version 1
--launch-template-data '{
"ImageId": "ami-0NEW_AMI_ID_HERE"
}'
# Instance Refresh başlat
aws autoscaling start-instance-refresh
--auto-scaling-group-name "webserver-asg"
--strategy Rolling
--preferences '{
"MinHealthyPercentage": 80,
"InstanceWarmup": 300,
"CheckpointPercentages": [20, 50, 100],
"CheckpointDelay": 600
}'
--desired-configuration '{
"LaunchTemplate": {
"LaunchTemplateId": "'$LT_ID'",
"Version": "2"
}
}'
# Durumu kontrol et
aws autoscaling describe-instance-refreshes
--auto-scaling-group-name "webserver-asg"
--query 'InstanceRefreshes[0].{Status:Status,PercentageComplete:PercentageComplete}'
MinHealthyPercentage parametresi kritik: %80 derseniz, 10 instance’lı bir grupta en az 8’i her zaman sağlıklı kalır. Refresh sırasında en fazla 2 instance aynı anda değiştirilir.
Gerçek Dünya Senaryosu: E-Ticaret Uygulaması
Bir e-ticaret sitesini düşünelim. Gece yarısı flash indirim kampanyası var ve trafik 10 kat artacak. Standart bir yapıda sunucu çöker. Auto Scaling ile şunları yaparsınız:
Önce Predictive Scaling kullanarak CloudWatch’un geçmiş veriyi analiz etmesini sağlarsınız. Önceki kampanyalardan öğrenen sistem, yeni kampanyadan önce kapasiteyi artırır.
Pratik olarak şu yaklaşım daha yaygındır: Kampanya saatinden 30 dakika önce manuel olarak desired capacity artırırsınız, sonra Target Tracking devralır:
# Kampanyadan 30 dk önce minimum kapasiteyi artır
aws autoscaling update-auto-scaling-group
--auto-scaling-group-name "webserver-asg"
--min-size 6
--desired-capacity 8
# Kampanya bitti, normale dön
aws autoscaling update-auto-scaling-group
--auto-scaling-group-name "webserver-asg"
--min-size 2
# Mevcut durumu kontrol et
aws autoscaling describe-auto-scaling-groups
--auto-scaling-group-names "webserver-asg"
--query 'AutoScalingGroups[0].{
Min:MinSize,
Max:MaxSize,
Desired:DesiredCapacity,
Running:length(Instances[?LifecycleState==`InService`])
}'
Lifecycle Hooks ile Gelişmiş Kontrol
Bazen yeni bir instance açıldığında ya da kapatılmadan önce özel işlemler yapmanız gerekir. Uygulamayı deregistre etmek, log’ları S3’e göndermek gibi.
# Launch hook: Instance açılırken beklet
aws autoscaling put-lifecycle-hook
--auto-scaling-group-name "webserver-asg"
--lifecycle-hook-name "instance-launching"
--lifecycle-transition "autoscaling:EC2_INSTANCE_LAUNCHING"
--notification-target-arn $SNS_ARN
--role-arn "arn:aws:iam::ACCOUNT_ID:role/EC2AutoScalingRole"
--heartbeat-timeout 300
--default-result CONTINUE
# Terminate hook: Kapatmadan önce beklet
aws autoscaling put-lifecycle-hook
--auto-scaling-group-name "webserver-asg"
--lifecycle-hook-name "instance-terminating"
--lifecycle-transition "autoscaling:EC2_INSTANCE_TERMINATING"
--notification-target-arn $SNS_ARN
--role-arn "arn:aws:iam::ACCOUNT_ID:role/EC2AutoScalingRole"
--heartbeat-timeout 120
--default-result CONTINUE
Lambda veya SSM Run Command ile hook’u tamamlayabilirsiniz:
# Hook'u manuel tamamla (test için)
aws autoscaling complete-lifecycle-action
--auto-scaling-group-name "webserver-asg"
--lifecycle-hook-name "instance-terminating"
--instance-id i-XXXXXXXXX
--lifecycle-action-result CONTINUE
Maliyet Optimizasyonu: Spot Instance Entegrasyonu
Production ortamında Spot Instance kullanmak ciddi tasarruf sağlar. Mixed Instances Policy ile On-Demand ve Spot’u karıştırabilirsiniz:
aws autoscaling update-auto-scaling-group
--auto-scaling-group-name "webserver-asg"
--mixed-instances-policy '{
"LaunchTemplate": {
"LaunchTemplateSpecification": {
"LaunchTemplateId": "'$LT_ID'",
"Version": "2"
},
"Overrides": [
{"InstanceType": "t3.medium"},
{"InstanceType": "t3a.medium"},
{"InstanceType": "t2.medium"}
]
},
"InstancesDistribution": {
"OnDemandBaseCapacity": 2,
"OnDemandPercentageAboveBaseCapacity": 20,
"SpotAllocationStrategy": "capacity-optimized"
}
}'
Bu yapıda ilk 2 instance her zaman On-Demand olacak. Onun üzerindeki instance’ların %20’si On-Demand, %80’i Spot olacak. capacity-optimized stratejisi Spot fiyat dalgalanmasından çok kapasiteye odaklanır, bu da daha az interruption anlamına gelir.
Sorun Giderme
En sık karşılaşılan sorunlar ve çözümleri:
- Instance’lar InService’e geçmiyor: Health check grace period’u artırın, user data script’ini inceleyin.
aws ec2 get-console-output --instance-id i-XXXile boot log’una bakın.
- Scaling çalışmıyor: CloudWatch alarmlarının ASG’ye bağlı olduğunu doğrulayın.
aws autoscaling describe-scaling-activitiesile aktivite geçmişini görün.
- Instance’lar sürekli açılıp kapanıyor (thrashing): Cooldown süresi çok kısa. Scale-in ve Scale-out eşiklerini ayrı tutun; örneğin scale-out %70 CPU’da, scale-in %40 CPU’da.
- Health check başarısız: ALB’nin hedef gruba ulaşıp ulaşamadığını kontrol edin. Security group’ta 80 portunun açık olduğunu doğrulayın.
ASG aktivitelerini düzenli takip etmek için:
# Son 20 aktiviteyi listele
aws autoscaling describe-scaling-activities
--auto-scaling-group-name "webserver-asg"
--max-items 20
--query 'Activities[*].{Time:StartTime,Status:StatusCode,Desc:Description}'
--output table
Sonuç
EC2 Auto Scaling kurulumu birden fazla AWS servisinin bir arada çalışmasını gerektiriyor: Launch Template, ASG, ALB, CloudWatch, IAM. Her biri ayrı bir konu olmakla birlikte bu bileşenler doğru birleştirildiğinde gerçekten self-healing ve maliyet etkin bir altyapı ortaya çıkıyor.
Başlangıç için tavsiyem şu: Target Tracking Policy ile CPU metriğini hedef alarak başlayın. Karmaşık step policy’lere gerek yok. Sistemi birkaç hafta izleyin, CloudWatch metriklerine bakın ve eşikleri gerçek trafik desenlerine göre ayarlayın.
Spot Instance entegrasyonunu hemen eklemeyin. Önce sistemin kararlı çalıştığını gördükten sonra mixed instances policy’yi devreye alın. Ve lifecycle hook’ları özellikle stateful uygulamalar için ihmal etmeyin; uygulamanızı düzgün kapamadan instance sonlandırırsanız veri kaybı veya bozuk state ile karşılaşırsınız.
Auto Scaling, bir kez kurduğunuzda sizi bırakmaz demiyorum ama düzgün kurulduğunda gece 3’te telefon çalmaktan sizi koruyan en değerli AWS servisidir.
