AWS Aurora Serverless Kurulumu ve Yapılandırması

Veritabanı yönetimi söz konusu olduğunda, “her zaman açık” sunucu tutmanın maliyeti ciddi bir kalem oluşturuyor. Özellikle geliştirme ortamları, test sistemleri veya trafiği öngörülemeyen uygulamalar için sabit kapasiteli bir RDS instance’ı ayakta tutmak hem pahalı hem de verimsiz. İşte tam bu noktada AWS Aurora Serverless devreye giriyor: kullanmadığında uyuyan, trafik geldiğinde otomatik olarak ölçeklenen ve saniye bazında faturalandırılan bir veritabanı motoru. Bu yazıda Aurora Serverless v2’yi sıfırdan kuracağız, gerçek dünya senaryolarında nasıl yapılandıracağımızı göreceğiz ve production’a almadan önce dikkat etmemiz gereken noktaları ele alacağız.

Aurora Serverless Nedir, Ne Değildir?

Aurora Serverless, Amazon Aurora’nın kapasiteyi otomatik olarak yönettiği bir dağıtım seçeneği. Klasik Aurora’da instance tipini seç, değiştirmen gerektiğinde maintenance window bekle. Serverless’ta ise “ACU” (Aurora Capacity Unit) cinsinden minimum ve maksimum kapasite belirle, gerisini AWS halleder.

v1 vs v2 farkına dikkat etmek gerekiyor. Aurora Serverless v1 artık yeni projeler için önerilmiyor. v1’de scale-down sırasında bağlantılar kesiliyor, cold start süresi dakikalar alabiliyordu. v2 bunları büyük ölçüde çözdü: milisaniyeler içinde ölçekleniyor, bağlantılar kesintisiz devam ediyor. Biz bu yazıda tamamen v2 üzerine odaklanacağız.

Aurora Serverless v2’nin mantığını şöyle özetleyebiliriz:

  • Minimum ACU: Veritabanının “uyku” halinde tutacağı minimum kaynak. 0 yaparsanız tamamen durur (yalnızca v1’de mümkündü, v2’de minimum 0.5 ACU).
  • Maximum ACU: Yük altında çıkabileceği üst sınır. Tek bir ACU yaklaşık 2 GB RAM ve buna orantılı CPU demek.
  • Pause/Resume: v2’de otomatik duraklama özelliği doğrudan yok, ama minimum ACU’yu düşük tutarak maliyeti minimize edebilirsin.

Ön Hazırlık: VPC ve Subnet Grubu

Aurora bir VPC içinde çalışır. Doğrudan public internet erişimi olmaz, olmamalı da. Önce altyapımızı hazırlayalım.

AWS CLI kurulu ve yapılandırılmış olduğunu varsayarak devam ediyorum. Eğer CLI yapılandırmadıysan:

aws configure
# AWS Access Key ID: [buraya access key]
# AWS Secret Access Key: [buraya secret key]
# Default region name: eu-west-1
# Default output format: json

Mevcut VPC’lerini listele ve hangi VPC’yi kullanacağını belirle:

# VPC listesi
aws ec2 describe-vpcs 
  --query 'Vpcs[*].{ID:VpcId,CIDR:CidrBlock,Name:Tags[?Key==`Name`].Value|[0]}' 
  --output table

# Seçtiğin VPC'nin subnet'lerini gör
VPC_ID="vpc-0abc123def456789"
aws ec2 describe-subnets 
  --filters "Name=vpc-id,Values=${VPC_ID}" 
  --query 'Subnets[*].{ID:SubnetId,AZ:AvailabilityZone,CIDR:CidrBlock,Public:MapPublicIpOnLaunch}' 
  --output table

Aurora için en az 2 farklı Availability Zone’da private subnet olması şart. Subnet grubu oluşturalım:

# DB Subnet Group oluştur
aws rds create-db-subnet-group 
  --db-subnet-group-name "aurora-serverless-subnet-group" 
  --db-subnet-group-description "Aurora Serverless v2 subnet grubu" 
  --subnet-ids 
    "subnet-0111aaa222bbb333c" 
    "subnet-0444ddd555eee666f" 
  --tags Key=Environment,Value=production Key=Project,Value=myapp

Şimdi Security Group hazırlayalım. Aurora’ya sadece uygulama sunucularından veya belirli IP bloklarından erişim olmalı:

# Security Group oluştur
SG_ID=$(aws ec2 create-security-group 
  --group-name "aurora-serverless-sg" 
  --description "Aurora Serverless erisim kurallari" 
  --vpc-id ${VPC_ID} 
  --query 'GroupId' 
  --output text)

echo "Security Group ID: ${SG_ID}"

# Uygulama sunucularinin Security Group'undan MySQL portuna izin ver
APP_SG_ID="sg-0aabbccdd11223344"
aws ec2 authorize-security-group-ingress 
  --group-id ${SG_ID} 
  --protocol tcp 
  --port 3306 
  --source-group ${APP_SG_ID}

# Bastion host'tan erişim için (geliştirme amaçlı)
BASTION_SG_ID="sg-0eeff99001122aabb"
aws ec2 authorize-security-group-ingress 
  --group-id ${SG_ID} 
  --protocol tcp 
  --port 3306 
  --source-group ${BASTION_SG_ID}

Aurora Serverless v2 Cluster Oluşturma

Şimdi asıl işe gelelim. Aurora Serverless v2’de önce bir cluster, sonra cluster’a bağlı bir instance oluşturursun. Instance’ın tipini db.serverless olarak belirtmek v2’yi aktif eder.

# Cluster parametreleri için önce bir parameter group oluştur
aws rds create-db-cluster-parameter-group 
  --db-cluster-parameter-group-name "aurora-serverless-params" 
  --db-cluster-family "aurora-mysql8.0" 
  --description "Aurora Serverless v2 parametre grubu"

# Önemli parametreleri ayarla
aws rds modify-db-cluster-parameter-group 
  --db-cluster-parameter-group-name "aurora-serverless-params" 
  --parameters 
    "ParameterName=character_set_server,ParameterValue=utf8mb4,ApplyMethod=pending-reboot" 
    "ParameterName=collation_server,ParameterValue=utf8mb4_unicode_ci,ApplyMethod=pending-reboot" 
    "ParameterName=slow_query_log,ParameterValue=1,ApplyMethod=pending-reboot" 
    "ParameterName=long_query_time,ParameterValue=2,ApplyMethod=pending-reboot"

Aurora cluster’ını oluştur:

# Master şifreyi güvenli şekilde üret
DB_PASSWORD=$(openssl rand -base64 24 | tr -dc 'A-Za-z0-9!@#$%' | head -c 20)
echo "DB Password: ${DB_PASSWORD}" # Bunu kaydet!

# Cluster oluştur
aws rds create-db-cluster 
  --db-cluster-identifier "myapp-aurora-serverless" 
  --engine "aurora-mysql" 
  --engine-version "8.0.mysql_aurora.3.04.0" 
  --master-username "admin" 
  --master-user-password "${DB_PASSWORD}" 
  --db-subnet-group-name "aurora-serverless-subnet-group" 
  --vpc-security-group-ids "${SG_ID}" 
  --db-cluster-parameter-group-name "aurora-serverless-params" 
  --serverless-v2-scaling-configuration 
    MinCapacity=0.5,MaxCapacity=8 
  --backup-retention-period 7 
  --preferred-backup-window "02:00-03:00" 
  --preferred-maintenance-window "sun:04:00-sun:05:00" 
  --enable-cloudwatch-logs-exports '["audit","error","general","slowquery"]' 
  --deletion-protection 
  --tags Key=Environment,Value=production Key=Project,Value=myapp

Burada --serverless-v2-scaling-configuration parametresi kritik. MinCapacity=0.5 minimum, MaxCapacity=8 maksimum ACU değerleri. Production için MaxCapacity’i uygulamanın peak trafiğine göre hesapla.

Şimdi Serverless v2 instance’ını cluster’a ekle:

aws rds create-db-instance 
  --db-instance-identifier "myapp-aurora-serverless-instance-1" 
  --db-cluster-identifier "myapp-aurora-serverless" 
  --db-instance-class "db.serverless" 
  --engine "aurora-mysql"

Cluster’ın hazır olmasını bekle:

# Cluster durumunu takip et
watch -n 30 'aws rds describe-db-clusters 
  --db-cluster-identifier myapp-aurora-serverless 
  --query "DBClusters[0].{Status:Status,Endpoint:Endpoint,ReaderEndpoint:ReaderEndpoint}" 
  --output table'

Status “available” olduğunda bağlantı bilgilerini kaydet.

Secrets Manager Entegrasyonu

Production ortamında veritabanı şifresini environment variable’a gömmek yerine AWS Secrets Manager kullanmak şart. Hem güvenlik hem de rotation kolaylığı açısından:

# Secret oluştur
aws secretsmanager create-secret 
  --name "myapp/aurora/credentials" 
  --description "Aurora Serverless master credentials" 
  --secret-string "{
    "username": "admin",
    "password": "${DB_PASSWORD}",
    "host": "myapp-aurora-serverless.cluster-xyz.eu-west-1.rds.amazonaws.com",
    "port": 3306,
    "dbname": "myapp"
  }"

# Otomatik rotation ayarla (her 30 günde bir)
aws secretsmanager rotate-secret 
  --secret-id "myapp/aurora/credentials" 
  --rotation-rules AutomaticallyAfterDays=30

Uygulama tarafında secret’ı okumak için basit bir Python örneği:

# Python ile secret okuma testi (boto3 kurulu olmalı)
python3 << 'EOF'
import boto3
import json

client = boto3.client('secretsmanager', region_name='eu-west-1')

response = client.get_secret_value(SecretId='myapp/aurora/credentials')
secret = json.loads(response['SecretString'])

print(f"Host: {secret['host']}")
print(f"Port: {secret['port']}")
print(f"Username: {secret['username']}")
print("Password: ****")
EOF

RDS Proxy ile Bağlantı Havuzu

Aurora Serverless v2 ile birlikte RDS Proxy kullanmak neredeyse zorunlu hale geliyor. Özellikle Lambda gibi serverless uygulama katmanlarında her function invocation yeni bir DB bağlantısı açar ve bu “too many connections” hatasına yol açar. RDS Proxy bu bağlantıları havuzlayarak yönetir.

# RDS Proxy için IAM Role oluştur
cat > rds-proxy-trust-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "rds.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

aws iam create-role 
  --role-name "rds-proxy-role" 
  --assume-role-policy-document file://rds-proxy-trust-policy.json

# Secrets Manager erişimi için policy ekle
aws iam put-role-policy 
  --role-name "rds-proxy-role" 
  --policy-name "rds-proxy-secrets-policy" 
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": [
          "secretsmanager:GetSecretValue",
          "secretsmanager:DescribeSecret"
        ],
        "Resource": "arn:aws:secretsmanager:eu-west-1:123456789012:secret:myapp/aurora/*"
      }
    ]
  }'

# RDS Proxy oluştur
PROXY_ROLE_ARN=$(aws iam get-role --role-name rds-proxy-role --query 'Role.Arn' --output text)

aws rds create-db-proxy 
  --db-proxy-name "myapp-aurora-proxy" 
  --engine-family "MYSQL" 
  --auth '{
    "AuthScheme": "SECRETS",
    "SecretArn": "arn:aws:secretsmanager:eu-west-1:123456789012:secret:myapp/aurora/credentials-AbCdEf",
    "IAMAuth": "REQUIRED"
  }' 
  --role-arn ${PROXY_ROLE_ARN} 
  --vpc-subnet-ids "subnet-0111aaa222bbb333c" "subnet-0444ddd555eee666f" 
  --vpc-security-group-ids ${SG_ID} 
  --require-tls

# Proxy'yi cluster'a bağla
aws rds register-db-proxy-targets 
  --db-proxy-name "myapp-aurora-proxy" 
  --db-cluster-identifiers "myapp-aurora-serverless"

CloudWatch Monitoring ve Alarmlar

Aurora Serverless’ın en kritik metrikleri ACU kullanımı ve bağlantı sayısı. Bunları izlemeden production’a almak tehlikeli:

# ACU kullanımı için alarm - maksimuma yaklaşıyorsa uyar
aws cloudwatch put-metric-alarm 
  --alarm-name "aurora-serverless-acu-high" 
  --alarm-description "Aurora ACU kullanimi yuksek" 
  --metric-name "ServerlessDatabaseCapacity" 
  --namespace "AWS/RDS" 
  --dimensions Name=DBClusterIdentifier,Value=myapp-aurora-serverless 
  --statistic Average 
  --period 300 
  --threshold 7 
  --comparison-operator GreaterThanOrEqualToThreshold 
  --evaluation-periods 2 
  --alarm-actions "arn:aws:sns:eu-west-1:123456789012:ops-alerts"

# Bağlantı sayısı alarmı
aws cloudwatch put-metric-alarm 
  --alarm-name "aurora-serverless-connections-high" 
  --alarm-description "Veritabani baglanti sayisi yuksek" 
  --metric-name "DatabaseConnections" 
  --namespace "AWS/RDS" 
  --dimensions Name=DBClusterIdentifier,Value=myapp-aurora-serverless 
  --statistic Average 
  --period 60 
  --threshold 200 
  --comparison-operator GreaterThanOrEqualToThreshold 
  --evaluation-periods 3 
  --alarm-actions "arn:aws:sns:eu-west-1:123456789012:ops-alerts"

Gerçek Dünya Senaryosu: Geliştirme Ortamı Maliyet Optimizasyonu

Bir e-ticaret projesinde geliştirme ve staging ortamları için Aurora Serverless’ın nasıl yapılandırılacağına bakalım. Bu ortamlarda gece ve hafta sonları veritabanının minimum kaynakta çalışması, iş saatlerinde hızlı ölçeklenmesi gerekiyor.

# Geliştirme ortamı için düşük kapasiteli cluster
aws rds create-db-cluster 
  --db-cluster-identifier "myapp-dev-aurora" 
  --engine "aurora-mysql" 
  --engine-version "8.0.mysql_aurora.3.04.0" 
  --master-username "devadmin" 
  --master-user-password "${DEV_PASSWORD}" 
  --db-subnet-group-name "aurora-serverless-subnet-group" 
  --vpc-security-group-ids "${SG_ID}" 
  --serverless-v2-scaling-configuration 
    MinCapacity=0.5,MaxCapacity=4 
  --backup-retention-period 1 
  --no-deletion-protection 
  --tags Key=Environment,Value=development Key=AutoShutdown,Value=enabled

# Lambda ile geceleri scale-down tetikle (örnek event scheduler)
aws scheduler create-schedule 
  --name "aurora-dev-scale-down-night" 
  --schedule-expression "cron(0 20 ? * MON-FRI *)" 
  --target '{
    "Arn": "arn:aws:lambda:eu-west-1:123456789012:function:aurora-scale-adjuster",
    "RoleArn": "arn:aws:iam::123456789012:role/scheduler-role",
    "Input": "{"clusterId": "myapp-dev-aurora", "minACU": 0.5, "maxACU": 1}"
  }' 
  --flexible-time-window '{"Mode": "OFF"}'

Backup ve Snapshot Yönetimi

# Manuel snapshot al (büyük deployment öncesinde)
aws rds create-db-cluster-snapshot 
  --db-cluster-identifier "myapp-aurora-serverless" 
  --db-cluster-snapshot-identifier "myapp-aurora-pre-release-$(date +%Y%m%d-%H%M)" 
  --tags Key=Reason,Value=pre-deployment Key=Version,Value=v2.5.0

# Snapshot listesini gör
aws rds describe-db-cluster-snapshots 
  --db-cluster-identifier "myapp-aurora-serverless" 
  --query 'DBClusterSnapshots[*].{ID:DBClusterSnapshotIdentifier,Status:Status,Time:SnapshotCreateTime}' 
  --output table

# Snapshot'tan yeni cluster oluştur (disaster recovery veya test için)
aws rds restore-db-cluster-from-snapshot 
  --db-cluster-identifier "myapp-aurora-restored" 
  --snapshot-identifier "myapp-aurora-pre-release-20240315-1430" 
  --engine "aurora-mysql" 
  --engine-version "8.0.mysql_aurora.3.04.0" 
  --db-subnet-group-name "aurora-serverless-subnet-group" 
  --vpc-security-group-ids "${SG_ID}" 
  --serverless-v2-scaling-configuration 
    MinCapacity=0.5,MaxCapacity=4

Scaling Kapasitesini Hesaplama

Pratikte MaxACU değerini nasıl belirleyeceksin? Mevcut bir RDS instance’ından geçiş yapıyorsan şu formülü kullanabilirsin:

  • db.t3.medium: 2 vCPU, 4 GB RAM — yaklaşık 2 ACU yeterli
  • db.r6g.large: 2 vCPU, 16 GB RAM — yaklaşık 8 ACU
  • db.r6g.xlarge: 4 vCPU, 32 GB RAM — yaklaşık 16 ACU

MaxACU hesaplamak için mevcut instance’ının peak CPU ve memory kullanımını CloudWatch’tan çek:

# Son 7 günün peak CPU kullanımını gör
aws cloudwatch get-metric-statistics 
  --namespace AWS/RDS 
  --metric-name CPUUtilization 
  --dimensions Name=DBInstanceIdentifier,Value=mevcut-rds-instance 
  --start-time $(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZ) 
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) 
  --period 3600 
  --statistics Maximum 
  --query 'sort_by(Datapoints, &Timestamp)[-1].Maximum'

# Freeable memory minimum değeri (ne kadar memory kullanılıyor hesaplamak için)
aws cloudwatch get-metric-statistics 
  --namespace AWS/RDS 
  --metric-name FreeableMemory 
  --dimensions Name=DBInstanceIdentifier,Value=mevcut-rds-instance 
  --start-time $(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZ) 
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) 
  --period 3600 
  --statistics Minimum 
  --query 'sort_by(Datapoints, &Timestamp)[0].Minimum'

Dikkat Edilmesi Gereken Noktalar

Production’a geçmeden önce bilmen gereken bazı önemli kısıtlamalar var:

  • Global Database: Aurora Serverless v2 artık Global Database ile birlikte kullanılabiliyor, ama Multi-Master desteklenmiyor.
  • Bazı özellikler desteklenmiyor: Backtrack özelliği Aurora Serverless ile çalışmıyor. Point-in-time recovery mevcut ama belirli kısıtları var.
  • Performance Insights: v2 ile birlikte Performance Insights kullanabilirsin, kesinlikle açık bırak.
  • Cold start sorunu v2’de de var mı?: v2’de minimum 0.5 ACU’da kalsa bile ilk bağlantıda küçük bir gecikme olabiliyor. Kritik uygulamalar için ısınma sorguları (warmup queries) göndermeyi düşün.
  • Maliyet tuzağı: MaxACU’yu çok yüksek bırakmak, anormal yük durumlarında (örneğin DDoS, runaway query) beklenmedik faturalara yol açabilir. Her zaman maksimum değer üzerinden bir maliyet sınırı belirle.
  • VPC içi iletişim: Aurora’ya sadece VPC içinden veya VPN/Direct Connect üzerinden erişilebilir. Bunu geliştirici ekibine net anlat, yoksa “neden bağlanamıyorum” soruları bitmez.
  • Engine version seçimi: Aurora MySQL 3.x, MySQL 8.0 uyumlu. Eski MySQL 5.7 uygulamalarını taşırken charset ve SQL mode farklılıklarına dikkat et.

Sonuç

Aurora Serverless v2, doğru senaryoda kullanıldığında hem maliyet hem de operasyon yükü açısından ciddi avantaj sağlıyor. Trafiği düzensiz olan SaaS uygulamaları, geliştirme ve staging ortamları, microservice mimarilerindeki küçük veritabanları ve Lambda tabanlı serverless uygulamalar için mükemmel bir seçim.

Ancak sürekli yüksek ve stabil trafiği olan, gecikmeye çok duyarlı ve her milisaniyenin kritik olduğu sistemlerde klasik Aurora provisioned instance daha iyi bir seçim olabilir. Veritabanı altyapısını seçerken “serverless trendy görünüyor” diye karar vermek yerine, iş yükünü analiz et, CloudWatch metriklerini takip et, pilot test yap ve sonra karara var.

Kurulum sonrasında yapmayı unutma şunları: Performance Insights aktif et, Enhanced Monitoring’i en az 60 saniye granülariteyle aç, CloudWatch alarmlarını kur, backup retention politikasını belirle ve mutlaka bir disaster recovery testi yap. Snapshot’tan restore ne kadar sürdüğünü bilmeden production’a almak, ileride sürpriz yaşatır.

Sorularınız veya farklı senaryolarınız varsa yorumlarda buluşalım.

Bir yanıt yazın

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