AWS Systems Manager ile Sunucu Yönetimi: Kapsamlı Rehber

Bulut altyapısı yönetirken en büyük baş ağrılarından biri sunuculara SSH ile bağlanmak, yamalar uygulamak, betikleri çalıştırmak ve tüm bu işlemleri izlemek. Özellikle onlarca, yüzlerce instance yönetiyorsanız bu süreç hızla kaosa dönüşebilir. AWS Systems Manager (SSM) tam da bu noktada devreye giriyor ve sunucu yönetimini merkezi, güvenli ve otomatize edilebilir bir hale getiriyor. Bu yazıda SSM’in günlük sysadmin hayatınızı nasıl değiştireceğini, gerçek dünya senaryolarıyla ele alacağız.

AWS Systems Manager Nedir ve Neden Önemlidir

AWS Systems Manager, EC2 instance’larınızı ve hatta on-premise sunucularınızı merkezi bir konsoldan yönetmenizi sağlayan bir hizmet bütünüdür. Tek bir araç değil, birçok özelliği bir arada sunan bir platform olarak düşünebilirsiniz.

Geleneksel yaklaşımda şöyle bir senaryo yaşanır: Güvenlik ekibi kritik bir CVE açıklar, siz de 50 sunucuya tek tek SSH açıp yamayı uygulamaya çalışırsınız. Yarısında işiniz bitmişken birinin yama uygulamasında hata çıkar, hangisinin güncel hangisinin eski kaldığını takip edemezsiniz. SSM ile bu senaryo tamamen değişir; Patch Manager ile tek tıkla tüm flotanıza yama uygulayabilir, Run Command ile betiklerinizi aynı anda yüzlerce sunucuda çalıştırabilirsiniz.

SSM’in öne çıkan bileşenleri şunlardır:

  • Session Manager: SSH olmadan güvenli terminal erişimi
  • Run Command: Uzaktan komut ve betik çalıştırma
  • Patch Manager: Otomatik yama yönetimi
  • Parameter Store: Hassas konfigurasyon verilerini saklama
  • Secrets Manager entegrasyonu: Parola ve API anahtarı yönetimi
  • Inventory: Donanım ve yazılım envanteri
  • State Manager: Konfigürasyon uyum yönetimi
  • Automation: Karmaşık operasyonları otomatize etme

SSM Agent Kurulumu ve IAM Rolü Yapılandırması

SSM kullanabilmek için instance’larınızda SSM Agent çalışıyor olmalı ve doğru IAM rolleri atanmış olmalıdır.

Yeni başlatılan Amazon Linux 2, Ubuntu 20.04+ ve Windows Server 2016+ instance’larında SSM Agent genellikle önceden yüklü gelir. Ancak eski instance’lar veya özel AMI’lar için manuel kurulum gerekebilir.

# Amazon Linux 2 / RHEL / CentOS için SSM Agent kurulumu
sudo yum install -y amazon-ssm-agent
sudo systemctl enable amazon-ssm-agent
sudo systemctl start amazon-ssm-agent

# Ubuntu için
sudo snap install amazon-ssm-agent --classic
sudo snap start amazon-ssm-agent
sudo snap enable amazon-ssm-agent

# Agent durumunu kontrol etme
sudo systemctl status amazon-ssm-agent

IAM tarafında, instance’ınıza atanmış olan IAM rolüne AmazonSSMManagedInstanceCore politikasını eklemeniz gerekiyor. Bu politika SSM’in temel fonksiyonları için gereken minimum izinleri içerir.

# AWS CLI ile mevcut instance'ın IAM profilini kontrol etme
aws ec2 describe-instances 
  --instance-ids i-1234567890abcdef0 
  --query 'Reservations[0].Instances[0].IamInstanceProfile'

# IAM rolüne SSM politikası ekleme
aws iam attach-role-policy 
  --role-name MyEC2Role 
  --policy-arn arn:aws:iam::aws:policies/AmazonSSMManagedInstanceCore

Dikkat edilmesi gereken önemli bir nokta: Instance’ın SSM endpoint’lerine erişebilmesi gerekiyor. Eğer private subnet’te çalışıyorsanız, VPC endpoint’leri oluşturmanız gerekir. Aksi halde SSM bağlantısı kurulamaz.

# SSM için gerekli VPC endpoint'lerini oluşturma
aws ec2 create-vpc-endpoint 
  --vpc-id vpc-12345678 
  --service-name com.amazonaws.eu-west-1.ssm 
  --vpc-endpoint-type Interface 
  --subnet-ids subnet-12345678 
  --security-group-ids sg-12345678

# SSM Messages endpoint
aws ec2 create-vpc-endpoint 
  --vpc-id vpc-12345678 
  --service-name com.amazonaws.eu-west-1.ssmmessages 
  --vpc-endpoint-type Interface 
  --subnet-ids subnet-12345678 
  --security-group-ids sg-12345678

Session Manager ile SSH’sız Güvenli Erişim

Session Manager, sysadmin olarak kullandığınızda “vay be” diyeceğiniz özelliklerden biri. Bastion host yok, SSH key yönetimi yok, 22. portu açmanıza gerek yok. Tüm oturumlar CloudTrail’e loglanıyor ve isteğe bağlı olarak S3’e kaydedilebiliyor.

# AWS CLI ile Session Manager oturumu başlatma
aws ssm start-session --target i-1234567890abcdef0

# Belirli bir port'a tünel açma (örneğin RDS için)
aws ssm start-session 
  --target i-1234567890abcdef0 
  --document-name AWS-StartPortForwardingSession 
  --parameters '{"portNumber":["3306"],"localPortNumber":["13306"]}'

# SSH tünel olarak kullanma (SSH config ile)
# ~/.ssh/config dosyasına ekleyin:
# Host i-* mi-*
#   ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

Gerçek dünyada bu özelliği bir fintech müşterisi için uyguladım. Müşterinin üretim sunucuları tamamen private subnet’teydi ve güvenlik politikası gereği bastion host bile kullanılmıyordu. Session Manager ile hem geliştirici ekibi hem de ops ekibi sunuculara güvenle bağlanabiliyor, tüm komut geçmişi S3’te saklanıyor ve herhangi bir compliance denetiminde bu logları anında sunabiliyorlardı.

Run Command ile Toplu İşlemler

Run Command, SSM’in en güçlü özelliklerinden biri. Yüzlerce instance’a aynı anda komut gönderebilir, sonuçları takip edebilir ve başarısız olanları kolayca belirleyebilirsiniz.

# Tüm web sunucularında Nginx servisini yeniden başlatma
aws ssm send-command 
  --targets "Key=tag:Role,Values=WebServer" 
  --document-name "AWS-RunShellScript" 
  --parameters '{"commands":["sudo systemctl restart nginx","sudo systemctl status nginx"]}' 
  --output-s3-bucket-name "my-ssm-logs" 
  --output-s3-key-prefix "run-command-logs"

# Komut sonuçlarını kontrol etme
aws ssm list-command-invocations 
  --command-id "12345678-1234-1234-1234-123456789012" 
  --details 
  --query 'CommandInvocations[*].[InstanceId,Status,CommandPlugins[0].Output]'

Toplu disk kullanımı kontrolü için pratik bir örnek verelim. Kapasitesi %80’i geçen sunucuları tespit etmek istiyorsunuz:

# Disk kullanımını kontrol eden betik
aws ssm send-command 
  --targets "Key=tag:Environment,Values=Production" 
  --document-name "AWS-RunShellScript" 
  --parameters '{
    "commands": [
      "#!/bin/bash",
      "THRESHOLD=80",
      "HOSTNAME=$(hostname)",
      "df -h | awk -v threshold=$THRESHOLD -v host=$HOSTNAME '''NR>1 && $5+0 > threshold {print host": "$0}'''",
      "exit 0"
    ]
  }' 
  --comment "Disk kullanim kontrolu"

Run Command sonuçlarını işlemek için bir Python betiği de işinize yarayabilir:

#!/bin/bash
# SSM Run Command sonuclarini toplayan ve raporlayan betik

COMMAND_ID=$(aws ssm send-command 
  --targets "Key=tag:Environment,Values=Production" 
  --document-name "AWS-RunShellScript" 
  --parameters '{"commands":["df -h --output=pcent / | tail -1 | tr -d " %""]}' 
  --query 'Command.CommandId' 
  --output text)

echo "Komut ID: $COMMAND_ID"
echo "Sonuclar bekleniyor..."
sleep 10

# Sonuclari topla
aws ssm list-command-invocations 
  --command-id "$COMMAND_ID" 
  --details 
  --query 'CommandInvocations[?Status==`Success`].[InstanceId,CommandPlugins[0].Output]' 
  --output table

Patch Manager ile Otomatik Yama Yönetimi

Patch Manager, sysadmin’lerin gecelerini rahat uyutacak özelliklerden biri. Yama grupları oluşturabilir, yama zamanlamaları yapabilir ve uyum raporları alabilirsiniz.

Önce bir patch baseline oluşturalım. Bu, hangi yamaların onaylı, hangilerinin reddedildiğini tanımlar:

# Kritik ve önemli güvenlik yamalarını otomatik onaylayan baseline
aws ssm create-patch-baseline 
  --name "ProductionLinuxBaseline" 
  --operating-system "AMAZON_LINUX_2" 
  --approval-rules '{
    "PatchRules": [
      {
        "PatchFilterGroup": {
          "PatchFilters": [
            {
              "Key": "SEVERITY",
              "Values": ["Critical", "Important"]
            },
            {
              "Key": "CLASSIFICATION",
              "Values": ["Security"]
            }
          ]
        },
        "ApproveAfterDays": 7,
        "ComplianceLevel": "CRITICAL",
        "EnableNonSecurity": false
      }
    ]
  }' 
  --description "Uretim ortami icin Linux yama baseline"

Patch gruplarını tag’ler ile yönetmek en temiz yaklaşım. Instance’larınıza Patch Group tag’i ekleyip baseline’ı bu gruba atayabilirsiniz:

# Instance'a patch group tag'i ekleme
aws ec2 create-tags 
  --resources i-1234567890abcdef0 
  --tags Key="Patch Group",Value="ProductionWebServers"

# Baseline'ı patch grubuna kaydetme
aws ssm register-patch-baseline-for-patch-group 
  --baseline-id "pb-12345678901234567" 
  --patch-group "ProductionWebServers"

# Maintenance window oluşturma (her Pazar 02:00'de)
aws ssm create-maintenance-window 
  --name "SundayNightPatching" 
  --schedule "cron(0 2 ? * SUN *)" 
  --duration 4 
  --cutoff 1 
  --allow-unassociated-targets

Parameter Store ile Konfigürasyon Yönetimi

Parameter Store, uygulama konfigürasyonlarını ve hassas verileri güvenle saklamak için mükemmel bir çözüm. Özellikle database şifreleri, API anahtarları ve ortam değişkenleri için kullanabilirsiniz.

# Basit string parametre ekleme
aws ssm put-parameter 
  --name "/myapp/production/db_host" 
  --value "mydb.cluster.eu-west-1.rds.amazonaws.com" 
  --type "String" 
  --description "Production veritabani host adresi"

# KMS ile sifrelenmi$ hassas parametre
aws ssm put-parameter 
  --name "/myapp/production/db_password" 
  --value "SuperSecretPassword123!" 
  --type "SecureString" 
  --key-id "alias/myapp-key" 
  --description "Production veritabani sifresi"

# Parametreyi okuma
aws ssm get-parameter 
  --name "/myapp/production/db_password" 
  --with-decryption 
  --query 'Parameter.Value' 
  --output text

# Bir path altindaki tum parametreleri listeleme
aws ssm get-parameters-by-path 
  --path "/myapp/production" 
  --with-decryption 
  --recursive

Bash betiklerinde Parameter Store kullanımı:

#!/bin/bash
# Uygulama konfigurasyonunu Parameter Store'dan alan betik

APP_ENV="production"
PARAM_PATH="/myapp/${APP_ENV}"

# Tum konfigurasyon degerlerini cek
echo "Konfigürasyon yukleniyoir..."

DB_HOST=$(aws ssm get-parameter 
  --name "${PARAM_PATH}/db_host" 
  --query 'Parameter.Value' 
  --output text)

DB_PASS=$(aws ssm get-parameter 
  --name "${PARAM_PATH}/db_password" 
  --with-decryption 
  --query 'Parameter.Value' 
  --output text)

API_KEY=$(aws ssm get-parameter 
  --name "${PARAM_PATH}/api_key" 
  --with-decryption 
  --query 'Parameter.Value' 
  --output text)

# Environment variable olarak export et
export DATABASE_HOST="$DB_HOST"
export DATABASE_PASSWORD="$DB_PASS"
export EXTERNAL_API_KEY="$API_KEY"

echo "Konfigürasyon basariyla yuklendi."
echo "DB Host: $DB_HOST"

Inventory ile Sunucu Envanteri

SSM Inventory, flotanızdaki tüm sunucuların yazılım, ağ, uygulama ve donanım bilgilerini otomatik olarak toplar. Özellikle lisans yönetimi ve güvenlik denetimleri için son derece değerli.

# Inventory association olusturma (her 30 dakikada bir toplama)
aws ssm create-association 
  --name "AWS-GatherSoftwareInventory" 
  --targets "Key=tag:Environment,Values=Production" 
  --schedule-expression "rate(30 minutes)" 
  --parameters '{
    "applications": ["Enabled"],
    "awsComponents": ["Enabled"],
    "networkConfig": ["Enabled"],
    "windowsUpdates": ["Disabled"],
    "services": ["Enabled"],
    "files": [
      {
        "Path": "/etc",
        "Pattern": ["*.conf"],
        "Recursive": "false",
        "DirScanLimit": "1000"
      }
    ]
  }'

# Envanteri sorgulama - hangi sunucularda Python 3.9 var?
aws ssm list-inventory-entries 
  --instance-id i-1234567890abcdef0 
  --type-name "AWS:Application" 
  --filters "Key=Name,Type=Equal,Values=Python 3"

Automation ile Karmaşık Operasyonları Otomatize Etme

SSM Automation, birden fazla adımdan oluşan karmaşık operasyonları tanımlamanıza ve çalıştırmanıza olanak sağlar. AMI oluşturma, instance kurtarma, DR senaryoları için ideal.

Gerçek dünya senaryosu: Bir e-ticaret platformu için her gece otomatik AMI yedeklemesi ve eski AMI’ların temizlenmesi:

# Automation document olusturma
aws ssm create-document 
  --name "CreateInstanceAMI" 
  --document-type "Automation" 
  --content '{
    "schemaVersion": "0.3",
    "description": "Instance AMI yedeklemesi olusturur ve eski yedekleri temizler",
    "parameters": {
      "InstanceId": {
        "type": "String",
        "description": "AMI olusturulacak instance ID"
      },
      "RetentionDays": {
        "type": "String",
        "default": "7",
        "description": "Kac gun saklanacak"
      }
    },
    "mainSteps": [
      {
        "name": "createAMI",
        "action": "aws:createImage",
        "inputs": {
          "InstanceId": "{{ InstanceId }}",
          "ImageName": "AutoBackup-{{ InstanceId }}-{{ global:DATE_TIME }}",
          "NoReboot": true
        }
      }
    ]
  }'

# Automation'i calistirma
aws ssm start-automation-execution 
  --document-name "CreateInstanceAMI" 
  --parameters "InstanceId=i-1234567890abcdef0,RetentionDays=7"

# Durumu takip etme
aws ssm describe-automation-executions 
  --filters "Key=DocumentNamePrefix,Values=CreateInstanceAMI" 
  --query 'AutomationExecutionMetadataList[0].{Status:AutomationExecutionStatus,Output:Outputs}'

Gerçek Dünya Senaryosu: Zero-Touch Deployment

Bir startup müşterisi için kurduğum pipeline’ı anlatayım. Uygulama güncellemelerini SSM üzerinden yapmak istediler, SSH erişimi hiç olmadan.

Senaryo şöyle: GitHub Actions CI/CD pipeline’ı kodu derliyor, S3’e yüklüyor ve SSM Run Command tetikliyor. Sunucular kodu S3’ten çekip uyguluyor.

#!/bin/bash
# deploy.sh - GitHub Actions tarafindan tetiklenen deployment betiği

set -e

ENVIRONMENT="${1:-staging}"
APP_VERSION="${2:-latest}"
S3_BUCKET="myapp-deployments"
TAG_KEY="Environment"
TAG_VALUE="$ENVIRONMENT"

echo "=== Deployment basliyor: $APP_VERSION -> $ENVIRONMENT ==="

# Kodu S3'e yukle
aws s3 cp ./dist.tar.gz "s3://${S3_BUCKET}/${APP_VERSION}/dist.tar.gz"

# SSM Run Command ile deployment'i baslat
COMMAND_ID=$(aws ssm send-command 
  --targets "Key=tag:${TAG_KEY},Values=${TAG_VALUE}" 
  --document-name "AWS-RunShellScript" 
  --parameters "{
    "commands": [
      "set -e",
      "APP_VERSION=${APP_VERSION}",
      "S3_BUCKET=${S3_BUCKET}",
      "echo Yeni versiyon indiriliyor: $APP_VERSION",
      "aws s3 cp s3://${S3_BUCKET}/${APP_VERSION}/dist.tar.gz /tmp/",
      "sudo systemctl stop myapp || true",
      "sudo tar -xzf /tmp/dist.tar.gz -C /opt/myapp/",
      "sudo chown -R appuser:appuser /opt/myapp/",
      "sudo systemctl start myapp",
      "sudo systemctl is-active myapp && echo DEPLOYMENT_OK || echo DEPLOYMENT_FAILED",
      "rm -f /tmp/dist.tar.gz"
    ]
  }" 
  --timeout-seconds 300 
  --query 'Command.CommandId' 
  --output text)

echo "Komut ID: $COMMAND_ID"

# Tamamlanmasini bekle
MAX_WAIT=60
COUNTER=0
while [ $COUNTER -lt $MAX_WAIT ]; do
  STATUS=$(aws ssm list-commands 
    --command-id "$COMMAND_ID" 
    --query 'Commands[0].StatusDetails' 
    --output text)
  
  echo "Durum: $STATUS"
  
  if [ "$STATUS" = "Success" ]; then
    echo "Deployment basarili!"
    exit 0
  elif [ "$STATUS" = "Failed" ] || [ "$STATUS" = "TimedOut" ]; then
    echo "Deployment basarisiz!"
    exit 1
  fi
  
  sleep 5
  COUNTER=$((COUNTER + 1))
done

echo "Deployment zaman asimina ugradi!"
exit 1

Maliyetleri Kontrol Altında Tutma

SSM’in çoğu özelliği ücretsiz. Ancak bazı noktaları göz önünde bulundurmanız gerekiyor:

  • Session Manager: Ücretsiz, ancak S3’e log yazıyorsanız S3 maliyeti oluşur
  • Parameter Store: Standart parametreler ücretsiz (ilk 10.000), advanced parametreler ücretli
  • Patch Manager: EC2 instance’ları için ücretsiz, on-premise sunucular için ücretli
  • Automation: Standart adımlar ücretsiz, bazı özel adımlar ücretli

Advanced parametrelerle standart parametreler arasındaki fark önemli: Advanced parametreler daha büyük değerler saklayabilir (8KB vs 4KB) ve parametre politikaları tanımlayabilirsiniz. Küçük ölçekli kullanımda standart parametreler genellikle yeterli olur.

CloudWatch Entegrasyonu ve İzleme

SSM aktivitelerini izlemek için CloudWatch ve CloudTrail entegrasyonunu mutlaka kurun:

# SSM aktivitelerini izleyen CloudWatch alarm
aws cloudwatch put-metric-alarm 
  --alarm-name "SSMRunCommandFailures" 
  --alarm-description "SSM Run Command basarisizliklari" 
  --namespace "AWS/SSM-RunCommand" 
  --metric-name "CommandsFailed" 
  --dimensions Name=CommandId,Value=all 
  --statistic Sum 
  --period 300 
  --evaluation-periods 1 
  --threshold 5 
  --comparison-operator GreaterThanThreshold 
  --alarm-actions "arn:aws:sns:eu-west-1:123456789012:ops-alerts"

Session Manager için oturum loglarını S3’e yazan bir konfigürasyon:

# Session Manager tercihlerini guncelleme
aws ssm update-document 
  --name "SSM-SessionManagerRunShell" 
  --content '{
    "schemaVersion": "1.0",
    "description": "Session Manager tercih dokumani",
    "sessionType": "Standard_Stream",
    "inputs": {
      "s3BucketName": "my-session-logs",
      "s3KeyPrefix": "session-manager",
      "s3EncryptionEnabled": true,
      "cloudWatchLogGroupName": "/aws/ssm/sessions",
      "cloudWatchEncryptionEnabled": true,
      "idleSessionTimeout": "20"
    }
  }' 
  --document-version "$LATEST"

Sonuç

AWS Systems Manager, modern bir sysadmin’in araç kutusunda olması gereken temel bileşenlerden biri haline geldi. SSH key yönetiminin getirdiği güvenlik risklerini ortadan kaldırması, toplu komut çalıştırma ve yama yönetiminin operasyonel yükü azaltması, Parameter Store ile konfigürasyon yönetimini merkezileştirmesi açısından SSM gerçek bir oyun değiştirici.

Başlangıç olarak en kritik sunucularınıza SSM Agent kurup Session Manager’ı aktif edin. Bastion host bağımlılığınızı ortadan kaldırın ve tüm oturumları loglamaya başlayın. Bir sonraki adımda Patch Manager ile yama süreçlerinizi otomatize edin. Zamanla Run Command, Automation ve Parameter Store entegrasyonlarını ekledikçe hem güvenlik duruşunuz güçlenecek hem de operasyonel verimliliğiniz ciddi ölçüde artacak.

En önemlisi, tüm bu araçları kullanırken least privilege prensibini asla unutmayın. SSM güçlü bir araç, doğru IAM politikaları olmadan bu güç kolayca kötüye kullanılabilir. Her bileşen için ayrı roller ve politikalar tanımlayın, düzenli olarak gözden geçirin.

Bir yanıt yazın

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