AWS CLI ile S3 Dosya İşlemleri: Kapsamlı Rehber
Bulut altyapısını yönetirken en çok zaman harcadığın yerlerden biri dosya transferleri ve depolama yönetimidir. AWS S3, bu iş için son derece güçlü bir servis ama grafik arayüzü üzerinden çalışmak hem yavaş hem de otomasyon için uygun değil. İşte tam bu noktada AWS CLI devreye giriyor. Bir kez komut satırını öğrendiğinde, S3 üzerindeki tüm işlemlerini script’lere döküp dakikalar içinde halledebiliyorsun.
Bu yazıda AWS CLI’yi S3 ile birlikte nasıl verimli kullanacağını gerçek dünya senaryoları üzerinden anlatacağım. Temel komutlardan başlayıp yedekleme scriptlerine, lifecycle yönetimine kadar her şeye değineceğiz.
AWS CLI Kurulumu ve Yapılandırması
Başlamadan önce ortamın hazır olması gerekiyor. AWS CLI’nin v2 sürümünü kullanmanı öneriyorum çünkü v1 ile karşılaştırıldığında performans farkı oldukça belirgin.
Linux için kurulum:
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Kurulumu doğrula
aws --version
Kurulumdan sonra credential’ları yapılandırman gerekiyor. Production ortamında IAM role kullanmak en güvenli yol ama lokal geliştirme için access key yöntemi de işe yarıyor.
aws configure
# AWS Access Key ID: AKIAIOSFODNN7EXAMPLE
# AWS Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# Default region name: eu-west-1
# Default output format: json
Birden fazla AWS hesabıyla çalışıyorsan profile sistemi hayat kurtarıcı. Örneğin hem production hem de staging ortamların varsa:
# Production profili
aws configure --profile production
# Staging profili
aws configure --profile staging
# Belirli profili kullanmak için
aws s3 ls --profile production
~/.aws/credentials dosyasını doğrudan düzenleyerek de profil ekleyebilirsin. Yönetimesi daha kolay olur çoğu zaman.
Temel S3 Komutları
AWS CLI’nin S3 için iki farklı komut kümesi var: aws s3 ve aws s3api. İlki yüksek seviyeli ve kullanıcı dostu, ikincisi ise düşük seviyeli S3 API’sini doğrudan çağırıyor. Çoğu günlük iş için aws s3 yeterli.
Bucket Listeleme ve Yönetimi
# Tüm bucket'ları listele
aws s3 ls
# Belirli bir bucket'ın içeriğini listele
aws s3 ls s3://my-company-backups
# Alt klasörlerle birlikte recursive listele
aws s3 ls s3://my-company-backups/logs/ --recursive
# İnsan okunabilir boyutlarla listele
aws s3 ls s3://my-company-backups --recursive --human-readable --summarize
--summarize parametresi toplam dosya sayısını ve boyutunu gösteriyor, büyük bucket’larda ne kadar alan kullandığını anlamak için çok işe yarıyor.
Yeni bucket oluşturma:
# Bucket oluştur (us-east-1 dışındaki regionlar için location-constraint zorunlu)
aws s3 mb s3://my-new-bucket --region eu-west-1
# Bucket sil (önce içini boşaltman gerekiyor)
aws s3 rb s3://my-empty-bucket
# İçeriğiyle birlikte sil (dikkatli ol!)
aws s3 rb s3://my-bucket --force
Dosya Yükleme ve İndirme
Günlük işlerin büyük çoğunluğu dosya transfer komutlarından oluşuyor. cp, mv ve sync üçlüsü en sık kullandığın komutlar olacak.
# Tek dosya yükle
aws s3 cp /local/path/backup.tar.gz s3://my-company-backups/
# Dosya indir
aws s3 cp s3://my-company-backups/backup.tar.gz /local/downloads/
# Klasörü yükle (recursive)
aws s3 cp /var/log/nginx/ s3://my-company-logs/nginx/ --recursive
# Belirli dosya uzantılarını hariç tut
aws s3 cp /var/www/html/ s3://my-website-bucket/ --recursive --exclude "*.log" --exclude "*.tmp"
# Sadece belirli dosyaları dahil et
aws s3 cp /var/www/html/ s3://my-website-bucket/ --recursive --exclude "*" --include "*.html" --include "*.css"
--exclude ve --include parametrelerinin sırası önemli. --exclude "*" ile önce her şeyi dışla, sonra --include ile istediklerini ekle mantığıyla çalışıyor.
Sync Komutu: Gerçek Güç Burda
sync komutu, klasörler arasındaki farkı algılayıp sadece değişen dosyaları transfer eden akıllı bir komut. Büyük veri setleri için cp --recursive‘den çok daha verimli.
# Lokal klasörü S3'e sync et
aws s3 sync /var/www/html/ s3://my-website-bucket/
# S3'ten lokal klasöre sync et
aws s3 sync s3://my-website-bucket/ /var/www/html/
# S3 bucket'ları arası sync
aws s3 sync s3://source-bucket/ s3://destination-bucket/
# Silinenleri de hedefte sil (dikkatli kullan!)
aws s3 sync /local/path/ s3://my-bucket/ --delete
# Önce ne olacağını gör, ama uygulama
aws s3 sync /local/path/ s3://my-bucket/ --dryrun
--delete parametresini üretim ortamında kullanmadan önce mutlaka --dryrun ile test et. Kaç dosyanın silineceğini görmeden bu parametreyle komutu çalıştırmak tehlikeli olabilir.
Transfer Hızlandırma ve Büyük Dosyalar
Büyük dosyaları transfer ederken performansı artırmak için birkaç parametre var.
# Paralel transfer sayısını artır
aws s3 cp large-backup.tar.gz s3://my-bucket/
--storage-class STANDARD_IA
--expected-size 10737418240
# Multipart upload eşiğini ve chunk boyutunu ayarla
aws configure set default.s3.multipart_threshold 64MB
aws configure set default.s3.multipart_chunksize 16MB
aws configure set default.s3.max_concurrent_requests 20
# Bant genişliğini sınırla (MB/s cinsinden)
aws s3 cp large-file.tar.gz s3://my-bucket/ --no-progress
Multipart upload ayarlarını ~/.aws/config dosyasında da kalıcı olarak yapabilirsin:
[default]
s3 =
multipart_threshold = 64MB
multipart_chunksize = 16MB
max_concurrent_requests = 20
max_queue_size = 1000
Storage Class Yönetimi
S3’ün maliyet optimizasyonu için farklı storage class seçenekleri var. Doğru seçim yapmak ciddi para tasarrufu sağlayabiliyor.
# Standart IA'ya yükle (sık erişilmeyen veriler için)
aws s3 cp database-backup.tar.gz s3://my-bucket/ --storage-class STANDARD_IA
# Glacier'a arşivle
aws s3 cp old-logs.tar.gz s3://my-bucket/archive/ --storage-class GLACIER
# Mevcut nesnenin storage class'ını değiştir
aws s3 cp s3://my-bucket/old-file.tar.gz s3://my-bucket/old-file.tar.gz
--storage-class GLACIER
--metadata-directive COPY
Storage class seçimi için genel kural:
- STANDARD: Sık erişilen, kritik veriler
- STANDARD_IA: Ayda birkaç kez erişilen yedekler
- GLACIER: Yıllık arşivler, yasal saklama zorunlulukları
- GLACIER_DEEP_ARCHIVE: 7-10 yıllık uzun süreli arşivler
Gerçek Dünya Senaryosu: Otomatik Yedekleme Script’i
Şimdi işe yarar bir şey yazalım. Aşağıdaki script, MySQL veritabanı yedeğini alıp S3’e yükleyen ve 30 günden eski yedekleri temizleyen bir yapı kuruyor.
#!/bin/bash
# Konfigürasyon
DB_HOST="localhost"
DB_USER="backup_user"
DB_PASS="secure_password"
DB_NAME="production_db"
S3_BUCKET="my-company-backups"
S3_PREFIX="mysql-backups"
BACKUP_DIR="/tmp/db_backups"
RETENTION_DAYS=30
DATE=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_FILE="${DB_NAME}_${DATE}.sql.gz"
LOG_FILE="/var/log/s3_backup.log"
# Log fonksiyonu
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# Hata durumunda çık
set -e
trap 'log "HATA: Script beklenmedik şekilde sonlandı. Satır: $LINENO"' ERR
log "Yedekleme başlıyor: $DB_NAME"
# Backup dizinini oluştur
mkdir -p "$BACKUP_DIR"
# MySQL yedeği al
log "Veritabanı dump alınıyor..."
mysqldump
-h "$DB_HOST"
-u "$DB_USER"
-p"$DB_PASS"
--single-transaction
--routines
--triggers
"$DB_NAME" | gzip > "${BACKUP_DIR}/${BACKUP_FILE}"
BACKUP_SIZE=$(du -sh "${BACKUP_DIR}/${BACKUP_FILE}" | cut -f1)
log "Dump tamamlandı. Boyut: $BACKUP_SIZE"
# S3'e yükle
log "S3'e yükleniyor..."
aws s3 cp "${BACKUP_DIR}/${BACKUP_FILE}"
"s3://${S3_BUCKET}/${S3_PREFIX}/${BACKUP_FILE}"
--storage-class STANDARD_IA
--profile production
log "Yükleme tamamlandı: s3://${S3_BUCKET}/${S3_PREFIX}/${BACKUP_FILE}"
# Eski yedekleri S3'ten sil
log "Eski yedekler temizleniyor (${RETENTION_DAYS} günden eski)..."
CUTOFF_DATE=$(date -d "${RETENTION_DAYS} days ago" +%Y-%m-%d)
aws s3 ls "s3://${S3_BUCKET}/${S3_PREFIX}/" | while read -r line; do
FILE_DATE=$(echo "$line" | awk '{print $1}')
FILE_NAME=$(echo "$line" | awk '{print $4}')
if [[ "$FILE_DATE" < "$CUTOFF_DATE" ]] && [[ -n "$FILE_NAME" ]]; then
log "Siliniyor: $FILE_NAME"
aws s3 rm "s3://${S3_BUCKET}/${S3_PREFIX}/${FILE_NAME}" --profile production
fi
done
# Geçici dosyayı temizle
rm -f "${BACKUP_DIR}/${BACKUP_FILE}"
log "Yedekleme işlemi başarıyla tamamlandı."
Bu script’i crontab’a ekleyerek her gece çalıştırabilirsin:
# Her gece 02:00'de çalıştır
0 2 * * * /usr/local/bin/db_backup.sh >> /var/log/s3_backup.log 2>&1
S3 Nesne Metadata ve ACL Yönetimi
Dosyaları yüklerken metadata ve erişim kontrolü ayarlamaları da yapabilirsin.
# Content-Type ve cache-control ayarla
aws s3 cp index.html s3://my-website-bucket/
--content-type "text/html"
--cache-control "max-age=3600"
--metadata "author=sysadmin,version=1.2"
# Özel metadata ile yükle
aws s3 cp backup.tar.gz s3://my-bucket/
--metadata "backup-type=full,server=web01,retention=30days"
# Mevcut nesnenin metadata'sını görüntüle
aws s3api head-object
--bucket my-bucket
--key backup.tar.gz
# Presigned URL oluştur (7 günlük)
aws s3 presign s3://my-bucket/private-report.pdf
--expires-in 604800
Presigned URL’ler, S3’teki özel dosyaları geçici olarak dışarıya açmak için mükemmel. Müşterilere dosya paylaşmak ya da webhook’larla geçici erişim vermek için sık kullanılan bir yöntem.
Bucket Policy ve Erişim Yönetimi
aws s3api komutunu kullanarak bucket policy’leri yönetebilirsin.
# Bucket policy görüntüle
aws s3api get-bucket-policy
--bucket my-bucket
--query Policy
--output text | python3 -m json.tool
# Bucket policy uygula
cat > /tmp/bucket-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/WebServerRole"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
EOF
aws s3api put-bucket-policy
--bucket my-bucket
--policy file:///tmp/bucket-policy.json
# Public access bloğunu etkinleştir
aws s3api put-public-access-block
--bucket my-bucket
--public-access-block-configuration
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
Production bucket’larında public access block’u her zaman açık tutmayı alışkanlık haline getir. Yanlışlıkla yapılan bir ACL değişikliği nedeniyle hassas veriyi ifşa etme riskini ortadan kaldırır.
Lifecycle Policy ile Maliyet Optimizasyonu
Lifecycle policy’ler, nesneleri belirli süreler sonra otomatik olarak farklı storage class’lara taşıyan ya da silen kurallardır.
cat > /tmp/lifecycle-policy.json << 'EOF'
{
"Rules": [
{
"ID": "BackupLifecycle",
"Status": "Enabled",
"Filter": {
"Prefix": "mysql-backups/"
},
"Transitions": [
{
"Days": 30,
"StorageClass": "STANDARD_IA"
},
{
"Days": 90,
"StorageClass": "GLACIER"
}
],
"Expiration": {
"Days": 365
}
}
]
}
EOF
# Lifecycle policy uygula
aws s3api put-bucket-lifecycle-configuration
--bucket my-company-backups
--lifecycle-configuration file:///tmp/lifecycle-policy.json
# Mevcut lifecycle policy'yi görüntüle
aws s3api get-bucket-lifecycle-configuration
--bucket my-company-backups
Bu policy ile yedekler 30 gün sonra STANDARD_IA’ya, 90 gün sonra Glacier’a taşınıyor ve 1 yıl sonra otomatik siliniyor. Yedek maliyetlerinde ciddi bir düşüş sağlıyor.
Çoklu Bölge Replikasyonu Kontrol Etme
Disaster recovery senaryoları için farklı region’lara replikasyon kuruyorsan, replikasyon durumunu CLI üzerinden takip edebilirsin.
# Replikasyon konfigürasyonunu görüntüle
aws s3api get-bucket-replication
--bucket my-primary-bucket
# Belirli bir nesnenin replikasyon durumunu kontrol et
aws s3api head-object
--bucket my-primary-bucket
--key important-file.tar.gz
--query '[ReplicationStatus, ContentLength, LastModified]'
# Bucket versioning durumunu kontrol et (replikasyon için zorunlu)
aws s3api get-bucket-versioning
--bucket my-primary-bucket
# Versioning'i etkinleştir
aws s3api put-bucket-versioning
--bucket my-primary-bucket
--versioning-configuration Status=Enabled
CloudWatch Metrikleriyle S3 Monitoring
S3 bucket’larını izlemek için CloudWatch metriklerini CLI üzerinden sorgulayabilirsin.
# Son 24 saatteki bucket boyutunu sorgula
aws cloudwatch get-metric-statistics
--namespace AWS/S3
--metric-name BucketSizeBytes
--dimensions Name=BucketName,Value=my-company-backups Name=StorageType,Value=StandardStorage
--start-time $(date -d '1 day ago' --utc +%Y-%m-%dT%H:%M:%SZ)
--end-time $(date --utc +%Y-%m-%dT%H:%M:%SZ)
--period 86400
--statistics Average
--query 'Datapoints[0].Average'
--output text | awk '{printf "%.2f GBn", $1/1024/1024/1024}'
# Nesne sayısını sorgula
aws cloudwatch get-metric-statistics
--namespace AWS/S3
--metric-name NumberOfObjects
--dimensions Name=BucketName,Value=my-company-backups Name=StorageType,Value=AllStorageTypes
--start-time $(date -d '1 day ago' --utc +%Y-%m-%dT%H:%M:%SZ)
--end-time $(date --utc +%Y-%m-%dT%H:%M:%SZ)
--period 86400
--statistics Average
--output text
Hata Ayıklama ve Sorun Giderme
AWS CLI kullanırken karşılaştığın hataları daha iyi anlamak için debug modunu açabilirsin.
# Detaylı debug çıktısı
aws s3 cp large-file.tar.gz s3://my-bucket/ --debug 2>&1 | tee /tmp/aws-debug.log
# Sadece HTTP istek/cevap başlıklarını gör
aws s3 ls --debug 2>&1 | grep -E "(DEBUG|ERROR)"
# Bağlantı sorunlarını test et
aws s3 ls s3://my-bucket/
--endpoint-url https://s3.eu-west-1.amazonaws.com
--region eu-west-1
Sık karşılaşılan sorunlar ve çözümleri:
- AccessDenied: IAM role ya da policy’yi kontrol et, gerekli izinlerin tanımlandığından emin ol
- NoSuchBucket: Bucket adını ve region’ı doğrula
- RequestTimeTooSkewed: Sunucu saatini NTP ile senkronize et
- SlowDown hatası: Transfer hızını düşür ya da request’leri dağıt, throttling yaşanıyor
- SignatureDoesNotMatch: Sistem saatini kontrol et, AWS credential’larını yeniden yapılandır
Sonuç
AWS CLI ile S3 yönetimi, bir kez alıştıktan sonra grafik arayüzüne dönmek istemeyeceğin kadar verimli bir deneyim sunuyor. Bu yazıda anlattıklarımı özetlersek; temel dosya işlemlerinden lifecycle policy yönetimine, otomatik yedekleme scriptlerinden maliyet optimizasyonuna kadar geniş bir yelpazede pratik araçlar ve teknikler var.
Başlangıç olarak şu adımları atmalarını öneririm: önce aws s3 ls ve aws s3 cp komutlarına alış, sonra sync komutunu günlük iş akışına entegre et, ardından lifecycle policy’lerle maliyetleri düşürmeye bak. Son adım olarak da yedekleme süreçlerini script’e döküp cron ile otomatikleştir.
Şunu da eklemeliyim: AWS CLI komutlarını production ortamında çalıştırmadan önce her zaman --dryrun ya da ayrı bir test bucket’ı üzerinde dene. Yanlış yazılmış bir --delete parametresi ya da hatalı bir glob pattern, geri dönülmesi zor sonuçlar doğurabilir. Versioning’i aktif olan bucket’larda bu risk biraz daha düşük ama yine de dikkatli olmakta fayda var.
