AWS EC2 Snapshot Alma ve Geri Yükleme Rehberi

Bir production sunucusunda disk bozulması yaşadınız, uygulamanız çöktü ve yedek almayı unuttunuz. Bu senaryoyu yaşayan herkes bilir; o an ne kadar çaresiz hissettirdiğini anlatmak zor. AWS EC2 kullanıyorsanız şanslısınız, çünkü snapshot mekanizması tam da bu tür felaket anları için tasarlanmış. Ama snapshot almak kadar, onu doğru şekilde geri yüklemek de kritik bir beceri. Bu yazıda EC2 snapshot’larını A’dan Z’ye, gerçek dünya senaryolarıyla birlikte ele alacağız.

EC2 Snapshot Nedir ve Nasıl Çalışır?

EC2 snapshot’ları, EBS (Elastic Block Store) birimlerinin belirli bir andaki tam kopyasıdır. Ama basit bir “kopyala yapıştır” mantığıyla çalışmaz. AWS, artımlı (incremental) yedekleme teknolojisi kullanır. Yani ilk snapshot tüm diski kopyalar, sonraki snapshot’lar ise yalnızca değişen blokları kaydeder. Bu hem maliyet hem de hız açısından büyük avantaj sağlar.

Snapshot’lar S3’te saklanır ama siz bu bucket’ı doğrudan göremezsiniz. AWS bunu arka planda yönetir. Önemli bir nokta şu: Snapshot alma işlemi başladığında, o anki disk durumu anlık olarak “freeze” edilir ve veriler tutarlı bir şekilde kaydedilir. EBS birimi arka planda çalışmaya devam eder, yani uygulama kesintisi yaşamazsınız.

Snapshot’ların kullanım senaryoları oldukça geniş:

  • Disaster recovery: Sunucu bozulduğunda hızlı geri dönüş
  • Ortam kopyalama: Production’ı staging’e klonlamak
  • Migration: Bölgeler arası veri taşıma
  • Test amaçlı: Kritik değişiklikler öncesi güvenli nokta oluşturma
  • AMI oluşturma: Özelleştirilmiş makine imajları için temel

AWS CLI Kurulumu ve Yapılandırması

Snapshot işlemlerini hem AWS Console üzerinden hem de CLI ile yapabilirsiniz. Ancak bir sysadmin olarak CLI’ı tercih etmenizi öneririm, özellikle otomasyon söz konusu olduğunda vazgeçilmez.

# AWS CLI kurulumu (Ubuntu/Debian)
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

# Versiyon kontrolü
aws --version

# Yapılandırma
aws configure
# AWS Access Key ID: AKIAIOSFODNN7EXAMPLE
# AWS Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# Default region name: eu-west-1
# Default output format: json

Eğer EC2 instance üzerinden çalışıyorsanız ve instance’a uygun IAM rolü atanmışsa, aws configure yapmanıza gerek kalmaz. IAM rolü üzerinden otomatik kimlik doğrulama gerçekleşir. Production ortamlarında bu yöntemi tercih edin; access key’leri instance üzerinde tutmak güvenlik riski oluşturur.

Manuel Snapshot Alma

Önce mevcut instance ve volume bilgilerinizi öğrenmeniz gerekiyor.

# Çalışan instance'ları listele
aws ec2 describe-instances 
  --query 'Reservations[*].Instances[*].[InstanceId,State.Name,Tags[?Key==`Name`].Value|[0]]' 
  --output table

# Belirli bir instance'ın volume'larını bul
INSTANCE_ID="i-0abc123def456789"
aws ec2 describe-instances 
  --instance-ids $INSTANCE_ID 
  --query 'Reservations[0].Instances[0].BlockDeviceMappings[*].[DeviceName,Ebs.VolumeId]' 
  --output text

Volume ID’nizi öğrendikten sonra snapshot almak çok basit:

# Tek bir volume için snapshot al
VOLUME_ID="vol-0abc123def456789"
SNAPSHOT_DESC="prod-webserver-manual-backup-$(date +%Y%m%d-%H%M%S)"

aws ec2 create-snapshot 
  --volume-id $VOLUME_ID 
  --description "$SNAPSHOT_DESC" 
  --tag-specifications "ResourceType=snapshot,Tags=[{Key=Name,Value=$SNAPSHOT_DESC},{Key=Environment,Value=production},{Key=CreatedBy,Value=manuel}]"

Bu komut çalıştığında snapshot hemen hazır olmaz. Büyük disklerde saatler sürebilir. Snapshot durumunu kontrol etmek için:

# Snapshot durumunu kontrol et
SNAPSHOT_ID="snap-0abc123def456789"
aws ec2 describe-snapshots 
  --snapshot-ids $SNAPSHOT_ID 
  --query 'Snapshots[0].[SnapshotId,State,Progress,StartTime]' 
  --output text

Durum pending iken snapshot hala oluşuyor demektir. completed gördüğünüzde güvende olduğunuzu bilin.

Otomatik Snapshot Script’i

Gerçek prodüksiyonda manuel snapshot almak yeterli değil. Şöyle bir senaryo düşünün: Her gece saat 02:00’de tüm production sunucularınızın snapshot’ını almak istiyorsunuz, 7 günden eski olanları silmek istiyorsunuz. İşte tam da bu iş için kullanabileceğiniz bir script:

#!/bin/bash
# EC2 Auto Snapshot Script
# /usr/local/bin/ec2-snapshot.sh

set -euo pipefail

LOG_FILE="/var/log/ec2-snapshots.log"
RETENTION_DAYS=7
ENVIRONMENT_TAG="production"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# Bu instance'ın ID'sini al (instance metadata API)
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/region)

log "Snapshot işlemi başlıyor. Instance: $INSTANCE_ID, Bölge: $REGION"

# Instance'a bağlı tüm volume'ları bul
VOLUMES=$(aws ec2 describe-instances 
    --region $REGION 
    --instance-ids $INSTANCE_ID 
    --query 'Reservations[0].Instances[0].BlockDeviceMappings[*].Ebs.VolumeId' 
    --output text)

# Her volume için snapshot al
for VOLUME_ID in $VOLUMES; do
    log "Volume snapshot alınıyor: $VOLUME_ID"
    
    SNAPSHOT_NAME="${ENVIRONMENT_TAG}-${INSTANCE_ID}-${VOLUME_ID}-$(date +%Y%m%d-%H%M%S)"
    
    SNAPSHOT_ID=$(aws ec2 create-snapshot 
        --region $REGION 
        --volume-id $VOLUME_ID 
        --description "$SNAPSHOT_NAME" 
        --tag-specifications "ResourceType=snapshot,Tags=[{Key=Name,Value=$SNAPSHOT_NAME},{Key=Environment,Value=$ENVIRONMENT_TAG},{Key=InstanceId,Value=$INSTANCE_ID},{Key=AutoSnapshot,Value=true}]" 
        --query 'SnapshotId' 
        --output text)
    
    log "Snapshot oluşturuldu: $SNAPSHOT_ID"
done

# Eski snapshot'ları temizle
log "Eski snapshot'lar temizleniyor (${RETENTION_DAYS} günden eski)..."

OLD_DATE=$(date -d "${RETENTION_DAYS} days ago" +%Y-%m-%dT%H:%M:%S)

OLD_SNAPSHOTS=$(aws ec2 describe-snapshots 
    --region $REGION 
    --owner-ids self 
    --filters "Name=tag:AutoSnapshot,Values=true" 
              "Name=tag:InstanceId,Values=$INSTANCE_ID" 
    --query "Snapshots[?StartTime<'${OLD_DATE}'].SnapshotId" 
    --output text)

for SNAP_ID in $OLD_SNAPSHOTS; do
    log "Siliniyor: $SNAP_ID"
    aws ec2 delete-snapshot --region $REGION --snapshot-id $SNAP_ID
done

log "Snapshot işlemi tamamlandı."

Bu script’i crontab’a eklemek için:

# Script'e çalışma izni ver
sudo chmod +x /usr/local/bin/ec2-snapshot.sh

# Crontab'a ekle (her gece 02:00'de çalışır)
echo "0 2 * * * root /usr/local/bin/ec2-snapshot.sh" | sudo tee -a /etc/cron.d/ec2-snapshots

# Test için hemen çalıştır
sudo /usr/local/bin/ec2-snapshot.sh

Snapshot’tan Geri Yükleme

İşte kritik kısım. Sunucunuz çöktü ve snapshot’tan geri dönmeniz gerekiyor. Bu işlemin iki farklı yolu var.

Yöntem 1: Mevcut Instance’a Geri Yükleme

Bu yöntemi disk bozulması veya yanlış yapılandırma durumlarında kullanırsınız. Mevcut EBS volume’unu snapshot’la değiştirirsiniz.

#!/bin/bash
# Snapshot'tan volume geri yükleme

SNAPSHOT_ID="snap-0abc123def456789"
INSTANCE_ID="i-0abc123def456789"
DEVICE_NAME="/dev/xvda"  # Root disk için genellikle bu
REGION="eu-west-1"
AVAILABILITY_ZONE="eu-west-1a"

# Mevcut volume ID'sini bul
OLD_VOLUME_ID=$(aws ec2 describe-instances 
    --region $REGION 
    --instance-ids $INSTANCE_ID 
    --query 'Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==`'$DEVICE_NAME'`].Ebs.VolumeId' 
    --output text)

echo "Mevcut volume: $OLD_VOLUME_ID"

# Instance'ı durdur (root disk için zorunlu)
echo "Instance durduruluyor..."
aws ec2 stop-instances --region $REGION --instance-ids $INSTANCE_ID

# Instance'ın tamamen durmasını bekle
aws ec2 wait instance-stopped --region $REGION --instance-ids $INSTANCE_ID
echo "Instance durduruldu."

# Snapshot'tan yeni volume oluştur
echo "Yeni volume oluşturuluyor..."
NEW_VOLUME_ID=$(aws ec2 create-volume 
    --region $REGION 
    --availability-zone $AVAILABILITY_ZONE 
    --snapshot-id $SNAPSHOT_ID 
    --volume-type gp3 
    --tag-specifications "ResourceType=volume,Tags=[{Key=Name,Value=restored-from-${SNAPSHOT_ID}}]" 
    --query 'VolumeId' 
    --output text)

echo "Yeni volume: $NEW_VOLUME_ID"

# Volume'un hazır olmasını bekle
aws ec2 wait volume-available --region $REGION --volume-ids $NEW_VOLUME_ID
echo "Volume hazır."

# Eski volume'u ayır
echo "Eski volume ayrılıyor..."
aws ec2 detach-volume --region $REGION --volume-id $OLD_VOLUME_ID

aws ec2 wait volume-available --region $REGION --volume-ids $OLD_VOLUME_ID

# Yeni volume'u ekle
echo "Yeni volume ekleniyor..."
aws ec2 attach-volume 
    --region $REGION 
    --volume-id $NEW_VOLUME_ID 
    --instance-id $INSTANCE_ID 
    --device $DEVICE_NAME

# Instance'ı başlat
echo "Instance başlatılıyor..."
aws ec2 start-instances --region $REGION --instance-ids $INSTANCE_ID

aws ec2 wait instance-running --region $REGION --instance-ids $INSTANCE_ID
echo "Instance çalışıyor. Geri yükleme tamamlandı!"
echo "Eski volume ($OLD_VOLUME_ID) silinmeden önce test edin!"

Yöntem 2: Snapshot’tan Yeni Instance Oluşturma

Bu yöntem daha güvenlidir çünkü mevcut instance’a dokunmazsınız. Snapshot’tan önce AMI oluşturur, sonra bu AMI’dan yeni instance açarsınız.

# Snapshot'tan AMI oluştur
SNAPSHOT_ID="snap-0abc123def456789"
REGION="eu-west-1"

AMI_ID=$(aws ec2 register-image 
    --region $REGION 
    --name "restored-ami-$(date +%Y%m%d-%H%M%S)" 
    --description "Snapshot'tan geri yüklendi: $SNAPSHOT_ID" 
    --architecture x86_64 
    --root-device-name /dev/xvda 
    --block-device-mappings "DeviceName=/dev/xvda,Ebs={SnapshotId=$SNAPSHOT_ID,VolumeType=gp3,DeleteOnTermination=true}" 
    --virtualization-type hvm 
    --ena-support 
    --query 'ImageId' 
    --output text)

echo "AMI oluşturuldu: $AMI_ID"

# AMI'ın hazır olmasını bekle
aws ec2 wait image-available --region $REGION --image-ids $AMI_ID

# Yeni instance başlat
NEW_INSTANCE_ID=$(aws ec2 run-instances 
    --region $REGION 
    --image-id $AMI_ID 
    --instance-type t3.medium 
    --key-name my-keypair 
    --security-group-ids sg-0abc123def456789 
    --subnet-id subnet-0abc123def456789 
    --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=restored-instance}]" 
    --query 'Instances[0].InstanceId' 
    --output text)

echo "Yeni instance başlatıldı: $NEW_INSTANCE_ID"

Cross-Region Snapshot Kopyalama

Disaster recovery stratejinizin önemli bir parçası, snapshot’larınızı farklı bir AWS bölgesine kopyalamaktır. eu-west-1 bölgesi tamamen erişilemez hale gelirse (nadir ama olabilir), eu-central-1’deki kopyadan işi sürdürebilirsiniz.

#!/bin/bash
# Snapshot'ları farklı bölgeye kopyala

SOURCE_REGION="eu-west-1"
DEST_REGION="eu-central-1"
RETENTION_DAYS=30

# Kopyalanacak snapshot'ları bul (son 24 saatte oluşturulanlar)
YESTERDAY=$(date -d "1 day ago" +%Y-%m-%dT%H:%M:%S)

SNAPSHOTS=$(aws ec2 describe-snapshots 
    --region $SOURCE_REGION 
    --owner-ids self 
    --filters "Name=tag:AutoSnapshot,Values=true" 
    --query "Snapshots[?StartTime>='${YESTERDAY}'].SnapshotId" 
    --output text)

for SNAP_ID in $SNAPSHOTS; do
    echo "Kopyalanıyor: $SNAP_ID -> $DEST_REGION"
    
    # Snapshot açıklamasını al
    SNAP_DESC=$(aws ec2 describe-snapshots 
        --region $SOURCE_REGION 
        --snapshot-ids $SNAP_ID 
        --query 'Snapshots[0].Description' 
        --output text)
    
    # Hedef bölgeye kopyala
    NEW_SNAP_ID=$(aws ec2 copy-snapshot 
        --source-region $SOURCE_REGION 
        --source-snapshot-id $SNAP_ID 
        --destination-region $DEST_REGION 
        --description "DR-copy: $SNAP_DESC" 
        --query 'SnapshotId' 
        --output text 
        --region $DEST_REGION)
    
    echo "Kopya oluşturuldu: $NEW_SNAP_ID ($DEST_REGION)"
    
    # Hedef snapshot'a tag ekle
    aws ec2 create-tags 
        --region $DEST_REGION 
        --resources $NEW_SNAP_ID 
        --tags Key=Name,Value="DR-${SNAP_ID}" 
               Key=SourceRegion,Value=$SOURCE_REGION 
               Key=AutoSnapshot,Value=true
done

echo "Cross-region kopyalama tamamlandı."

AWS Data Lifecycle Manager ile Otomatik Yönetim

Script yazmak yerine AWS’nin yerleşik aracı olan Data Lifecycle Manager (DLM) kullanmak daha temiz bir çözüm. DLM ile snapshot politikaları tanımlayabilirsiniz.

# DLM policy oluşturmak için IAM rolü oluştur
aws iam create-role 
    --role-name AWSDataLifecycleManagerDefaultRole 
    --assume-role-policy-document '{
        "Version": "2012-10-17",
        "Statement": [{
            "Effect": "Allow",
            "Principal": {
                "Service": "dlm.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }]
    }'

# Lifecycle policy oluştur
aws dlm create-lifecycle-policy 
    --description "Production EC2 Daily Snapshots" 
    --state ENABLED 
    --execution-role-arn "arn:aws:iam::123456789012:role/AWSDataLifecycleManagerDefaultRole" 
    --policy-details '{
        "PolicyType": "EBS_SNAPSHOT_MANAGEMENT",
        "ResourceTypes": ["VOLUME"],
        "TargetTags": [{"Key": "Environment", "Value": "production"}],
        "Schedules": [{
            "Name": "DailySnapshots",
            "TagsToAdd": [{"Key": "AutoBackup", "Value": "DLM"}],
            "CreateRule": {
                "Interval": 24,
                "IntervalUnit": "HOURS",
                "Times": ["02:00"]
            },
            "RetainRule": {
                "Count": 7
            },
            "CopyTags": true
        }]
    }'

Bu komutu çalıştırdıktan sonra Environment=production etiketi olan tüm volume’lar her gece 02:00’de otomatik olarak yedeklenecek ve 7 kopya tutulacak. El ile bir şey yapmanıza gerek kalmaz.

Snapshot Maliyetlerini Optimize Etme

Snapshot’lar S3’te saklandığı için ücretlidir. Kontrol altında tutmak için birkaç öneri:

  • Artımlı yapıyı anlayın: İlk snapshot büyük, sonrakiler küçüktür. Sık sık snapshot almak düşündüğünüz kadar pahalı değildir.
  • Kullanılmayan snapshot’ları temizleyin: Silinen instance’ların snapshot’ları kalmaya devam eder.
  • Retention politikası belirleyin: 30 gün yeterli mi, 90 gün mü? Compliance gereksinimlerinize göre karar verin.
  • Bölge seçimine dikkat edin: Cross-region kopyalar hem storage hem transfer ücreti doğurur.
  • Gereksiz volume snapshot’larını birleştirin: Birden fazla data volume’u olan instance’larda kritik olmayan volume’lar için daha seyrek yedekleme yapabilirsiniz.

Mevcut snapshot maliyetinizi görmek için:

# Toplam snapshot sayısı ve boyutu
aws ec2 describe-snapshots 
    --owner-ids self 
    --query 'Snapshots[*].[SnapshotId,VolumeSize,StartTime,Description]' 
    --output table 
    --region eu-west-1

# Belirli ortama ait snapshot'ları listele
aws ec2 describe-snapshots 
    --owner-ids self 
    --filters "Name=tag:Environment,Values=production" 
    --query 'Snapshots[*].[SnapshotId,VolumeSize,StartTime]' 
    --output text 
    --region eu-west-1 | awk '{sum += $2} END {print "Toplam boyut (GB):", sum}'

Gerçek Dünya Senaryosu: Yanlış Silme Sonrası Kurtarma

Şöyle bir senaryo yaşandığını varsayalım: Bir gece geliştirici yanlışlıkla production veritabanı sunucusundaki /var/lib/mysql dizinini silmiş. Sunucu çalışıyor ama MySQL başlamıyor. Panik modunda siz devreye giriyorsunuz.

# 1. Mevcut durumu değerlendirin
aws ec2 describe-instances 
    --filters "Name=tag:Name,Values=prod-mysql-01" 
    --query 'Reservations[0].Instances[0].[InstanceId,State.Name]' 
    --output text

# 2. Son başarılı snapshot'ı bulun
INSTANCE_ID="i-0abc123def456789"
aws ec2 describe-snapshots 
    --owner-ids self 
    --filters "Name=tag:InstanceId,Values=$INSTANCE_ID" 
    --query 'sort_by(Snapshots, &StartTime)[-1].[SnapshotId,StartTime,Description]' 
    --output text

# 3. Durumu karşılaştırın - silme ne zaman oldu?
# Son snapshot 02:00'de alınmış, silme 14:30'da yaşanmış
# 12 saatlik veri kaybı söz konusu - bu kabul edilebilir mi?

# 4. Eğer kabul edilemezse: MySQL binary log'larını kurtarmayı deneyin
# (Bu konuyu ayrı bir yazıda ele alacağız)

# 5. Geri yükleme kararı alındığında yukarıdaki restore script'ini çalıştırın

Bu senaryo bize şunu öğretiyor: Sadece snapshot almak yetmez, recovery time objective (RTO) ve recovery point objective (RPO) değerlerini önceden belirlemeniz gerekir. Kaç saatlik veri kaybı kabul edilebilir? Bu sorunun cevabı, yedekleme sıklığınızı belirler.

Snapshot Güvenliği

Snapshot’larınız varsayılan olarak özeldir. Ama dikkat edilmesi gereken bazı noktalar var:

  • Şifreleme: KMS kullanarak snapshot’ları şifreleyebilirsiniz. Özellikle kişisel veri içeren sistemlerde bu zorunlu olmalı.
  • Paylaşım kontrolü: Snapshot’ları başka AWS hesaplarıyla paylaşmak mümkün. Bunu yanlışlıkla public yapmamaya dikkat edin.
  • Cross-account erişim: Farklı hesaplar arası snapshot kopyalamada KMS key paylaşımını doğru yapılandırın.
# Snapshot'u KMS ile şifreleyerek kopyala
aws ec2 copy-snapshot 
    --source-region eu-west-1 
    --source-snapshot-id snap-0abc123def456789 
    --destination-region eu-west-1 
    --region eu-west-1 
    --encrypted 
    --kms-key-id arn:aws:kms:eu-west-1:123456789012:key/mrk-abc123

Sonuç

EC2 snapshot yönetimi, cloud altyapısının temel taşlarından biri. İyi yapılandırılmış bir snapshot stratejisi, o kriz anında fark yaratır. Şu maddeleri özet olarak paylaşayım:

  • Otomasyonu kurun: Manuel snapshot almayı ihmal edersiniz. DLM veya cron tabanlı script ile otomasyonu kurun.
  • Test edin: Her üç ayda bir gerçek bir geri yükleme testi yapın. “Yedek var” ile “yedek çalışıyor” farklı şeyler.
  • Cross-region kopyalama: Kritik sistemlerde mutlaka farklı bölgede kopyası olsun.
  • Etiketleme disiplini: Snapshot’larınızı düzgün etiketleyin, sonra bulmanız zorlaşmasın.
  • Maliyeti izleyin: Günlük Cost Explorer kontrolü ile sürpriz fatura gelmesin.
  • RPO ve RTO belirleyin: Teknik değil, iş kararı. Bu değerler yedekleme sıklığınızı şekillendirir.

Snapshot stratejisini bir kez doğru kurun, sonra arkasına yaslanın. Çünkü o kriz anı geldiğinde, paniksiz hareket etmenizi sağlayan tek şey önceden yapılan hazırlıktır.

Bir yanıt yazın

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