AWS CLI Çıktı Formatları ve Filtreleme Teknikleri

AWS CLI ile çalışırken en çok zaman harcadığım konulardan biri çıktı yönetimiydi. Terminale dökülen JSON yığınları arasında aradığım bilgiyi bulmak, bazen AWS konsoluna geri dönmemi bile gerektirecek kadar can sıkıcı olabiliyordu. Ama doğru araçları öğrendikten sonra CLI, konsola kıyasla çok daha güçlü bir yönetim aracına dönüştü. Bu yazıda AWS CLI çıktı formatlarını, JMESPath sorgularını ve --query ile --filter parametrelerini gerçek dünya senaryolarıyla ele alacağız.

AWS CLI Çıktı Formatları

AWS CLI varsayılan olarak JSON formatında çıktı verir. Ama bu tek seçenek değil. Üç temel format var ve her birinin farklı kullanım senaryoları mevcut.

JSON Formatı

Varsayılan format. Otomasyon scriptlerinde, başka araçlarla entegrasyonda ve karmaşık veri işlemlerinde tercih edilir.

aws ec2 describe-instances --output json

JSON formatının avantajı veri bütünlüğünü koruması. Tüm alanları, iç içe geçmiş yapıları eksiksiz görürsünüz. Dezavantajı ise insan gözüyle okunabilirliğinin düşük olması. Onlarca instance çalışan bir ortamda sadece instance ID’lerini görmek istiyorsanız JSON çıktısını doğrudan okumak yorucu.

Text Formatı

Tab ile ayrılmış düz metin çıktısı. awk, grep, cut gibi Unix araçlarıyla çalışmak istediğinizde işinize yarar.

aws ec2 describe-instances --output text

Text formatı özellikle shell scriptlerinde faydalı. Ama dikkatli olmak gerekiyor, çıktı yapısı sorgulara göre değişebiliyor ve bazen beklenmedik satır kırılmaları yaşanabiliyor.

Table Formatı

İnsan gözüyle okunabilirlik için en iyi format. Terminalde hızlı kontroller yaparken idealdir.

aws ec2 describe-instances --output table

Tablo formatı görsel olarak düzenli ama script’lerde kullanmak için pek uygun değil. Hızlı durum kontrolleri için mükemmel.

Varsayılan Formatı Ayarlamak

Her komuta --output parametresi eklemek yerine, varsayılan formatı konfigürasyonda belirleyebilirsiniz:

aws configure set output table

Ya da belirli bir profil için:

aws configure set output json --profile production

–query Parametresi ve JMESPath

AWS CLI’nin en güçlü özelliklerinden biri --query parametresi. Bu parametre JMESPath sorgu dilini kullanıyor ve JSON çıktısı üzerinde filtreleme, dönüştürme yapmanıza olanak tanıyor.

Temel JMESPath Sözdizimi

JMESPath öğrenmek başta korkutucu görünebilir ama temel yapısı oldukça mantıklı.

Basit bir örnekle başlayalım. Tüm EC2 instance’larının ID’lerini listeleyelim:

aws ec2 describe-instances 
  --query 'Reservations[*].Instances[*].InstanceId' 
  --output text

Bu sorgu şu anlama geliyor: Reservations dizisinin tüm elemanlarına bak ([*]), her birinin Instances dizisinin tüm elemanlarına gir, oradan da InstanceId değerini al.

Çıktı şöyle görünür:

i-1234567890abcdef0
i-0987654321fedcba0
i-abcdef1234567890

Birden Fazla Alan Seçmek

Sadece ID değil, ID ile birlikte instance tipini ve durumunu da görmek istiyorsanız:

aws ec2 describe-instances 
  --query 'Reservations[*].Instances[*].[InstanceId, InstanceType, State.Name]' 
  --output table

Köşeli parantez içinde alan listesi verdiğinizde JMESPath bunları dizi olarak döndürür. State.Name kullanımına dikkat edin, iç içe geçmiş alanlara nokta notasyonuyla erişiyoruz.

Tag Değerlerine Göre Filtreleme

Gerçek dünya senaryosunda en çok ihtiyaç duyduğum şey tag’e göre filtreleme. Diyelim ki production ortamındaki tüm instance’ların isimlerini ve ID’lerini görmek istiyorum:

aws ec2 describe-instances 
  --filters "Name=tag:Environment,Values=production" 
  --query 'Reservations[*].Instances[*].[InstanceId, Tags[?Key==`Name`].Value | [0], State.Name]' 
  --output table

Bu sorgunun Tags[?Key==Name].Value | [0] kısmı biraz karmaşık görünüyor. Adım adım açıklayayım:

  • Tags[?Key==Name]: Tags dizisinde Key değeri “Name” olan elemanları filtrele
  • .Value: O elemanların Value alanını al
  • | [0]: Pipe ile ilk elemanı seç (genellikle tek bir Name tag’i olur)

Koşullu Filtreleme

Sadece “running” durumundaki instance’ları listelemek için:

aws ec2 describe-instances 
  --query 'Reservations[*].Instances[?State.Name==`running`].[InstanceId, InstanceType, PrivateIpAddress]' 
  --output table

[?koşul] sözdizimi JMESPath’te filtre ifadesi. ==, !=, <, >, <=, >= operatörleri kullanabilirsiniz. String değerleri backtick ile yazıyorsunuz.

Pratik Senaryolar

Senaryo 1: Aylık Maliyet Analizine Hazırlık

DevOps ekibine hangi instance’ların en uzun süredir çalıştığını rapor etmem gerekti. Launch time bilgisiyle birlikte instance listesi oluşturmak için:

aws ec2 describe-instances 
  --filters "Name=instance-state-name,Values=running" 
  --query 'Reservations[*].Instances[*].[InstanceId, InstanceType, LaunchTime, Tags[?Key==`Name`].Value | [0], Tags[?Key==`Owner`].Value | [0]]' 
  --output text | sort -k3

sort -k3 ile üçüncü kolona (LaunchTime) göre sıralıyoruz. En eski instance’lar en üstte görünüyor. Bu çıktıyı bir CSV’e yönlendirip finans ekibine gönderebilirsiniz.

Senaryo 2: Güvenlik Grubu Denetimi

Hangi security group’ların 0.0.0.0/0’dan gelen trafiğe izin verdiğini bulmak kritik. Özellikle SSH portunu (22) herkese açık bırakan grupları tespit etmek için:

aws ec2 describe-security-groups 
  --query "SecurityGroups[?IpPermissions[?IpRanges[?CidrIp=='0.0.0.0/0'] && FromPort==`22`]].[GroupId, GroupName, Description]" 
  --output table

Bu sorgu oldukça güçlü. Birden fazla iç içe geçmiş koşulu aynı anda değerlendiriyor. SSH portunu (22) herkese açmış tüm security group’ları bir anda görüyorsunuz. Güvenlik denetimlerinde bu tür sorgular saatler kazandırır.

Senaryo 3: S3 Bucket Boyutlarını Kontrol Etmek

S3 bucket’larının boyutunu CloudWatch Metrics üzerinden sorgulamak biraz dolaylı ama CLI ile yapılabilir. Önce bucket listesini alalım:

aws s3api list-buckets 
  --query 'Buckets[*].[Name, CreationDate]' 
  --output text

Belirli bir bucket’taki nesnelerin toplam boyutunu öğrenmek için:

aws s3api list-objects-v2 
  --bucket my-production-bucket 
  --query '[sum(Contents[*].Size), length(Contents[*])]' 
  --output text

sum() ve length() JMESPath fonksiyonları. sum() sayısal değerlerin toplamını, length() eleman sayısını döndürür. Bu çıktı byte cinsinden geliyor, insan okunabilir formata çevirmek için Python veya numfmt kullanabilirsiniz:

aws s3api list-objects-v2 
  --bucket my-production-bucket 
  --query 'sum(Contents[*].Size)' 
  --output text | numfmt --to=iec-i --suffix=B

Senaryo 4: RDS Instance Durumlarını İzlemek

Sabah monitöringe başlarken RDS cluster’larının durumunu kontrol etmek için kullandığım komut:

aws rds describe-db-instances 
  --query 'DBInstances[*].[DBInstanceIdentifier, DBInstanceStatus, DBInstanceClass, Engine, EngineVersion, MultiAZ]' 
  --output table

Sadece sorunlu instance’ları görmek istiyorsanız “available” olmayan olanları filtreleyin:

aws rds describe-db-instances 
  --query "DBInstances[?DBInstanceStatus!='available'].[DBInstanceIdentifier, DBInstanceStatus, DBInstanceClass]" 
  --output table

Bu komutu cron’a koyup çıktı boş değilse Slack’e bildirim gönderen basit bir script yazabilirsiniz.

–filters Parametresi ile Sunucu Taraflı Filtreleme

--query istemci taraflı filtreleme yapar: önce tüm veriyi çeker, sonra filtreler. --filters ise sunucu taraflı filtreleme yapar ve AWS API’sine hangi veriyi döndüreceğini söyler. Bu fark önemli, özellikle büyük ortamlarda.

# Sunucu taraflı filtreleme (daha verimli)
aws ec2 describe-instances 
  --filters "Name=instance-type,Values=t3.micro,t3.small" 
  --filters "Name=instance-state-name,Values=running"

# İstemci taraflı filtreleme (tüm veri çekilir, sonra filtrelenir)
aws ec2 describe-instances 
  --query "Reservations[*].Instances[?InstanceType=='t3.micro' || InstanceType=='t3.small']"

Büyük AWS hesaplarında yüzlerce instance varsa --filters kullanmak hem daha hızlı hem de API rate limit’lerine takılma riskini azaltır.

Kullanışlı –filters Örnekleri

# Belirli bir AMI ile başlatılan instance'lar
aws ec2 describe-instances 
  --filters "Name=image-id,Values=ami-0abcdef1234567890"

# Belirli bir subnet'teki instance'lar
aws ec2 describe-instances 
  --filters "Name=subnet-id,Values=subnet-12345678"

# Belirli bir key pair kullanan instance'lar
aws ec2 describe-instances 
  --filters "Name=key-name,Values=my-production-key"

# Tag anahtarı var mı kontrolü
aws ec2 describe-instances 
  --filters "Name=tag-key,Values=backup"

JMESPath Fonksiyonları

JMESPath birçok built-in fonksiyon sunuyor. En çok kullandıklarım:

length(@): Dizinin eleman sayısını verir. Kaç instance çalıştığını hızlıca görmek için:

aws ec2 describe-instances 
  --filters "Name=instance-state-name,Values=running" 
  --query 'length(Reservations[*].Instances[*])' 
  --output text

sort_by(): Belirli bir alana göre sıralama yapar. Instance’ları launch time’a göre sıralamak için:

aws ec2 describe-instances 
  --query 'sort_by(Reservations[*].Instances[*], &LaunchTime)[*].[InstanceId, LaunchTime]' 
  --output table

& işareti expression referansı için kullanılıyor. sort_by() fonksiyonu hangi alana göre sıralayacağını bulmak için bu referansa ihtiyaç duyuyor.

max_by() ve min_by(): Belirli bir alana göre maksimum veya minimum değere sahip elemanı bulur:

# En yeni başlatılan instance'ı bul
aws ec2 describe-instances 
  --query 'max_by(Reservations[*].Instances[*][], &LaunchTime).[InstanceId, LaunchTime, InstanceType]' 
  --output table

Çıktıyı Dosyaya Yönlendirmek ve İşlemek

Otomasyon scriptlerinde CLI çıktısını değişkene atamak veya dosyaya kaydetmek çok yaygın.

# Değişkene atama
INSTANCE_IDS=$(aws ec2 describe-instances 
  --filters "Name=tag:Environment,Values=production" 
               "Name=instance-state-name,Values=running" 
  --query 'Reservations[*].Instances[*].InstanceId' 
  --output text)

echo "Production'da çalışan instance'lar: $INSTANCE_IDS"

# Bu instance'ları döngüyle işlemek
for instance_id in $INSTANCE_IDS; do
  echo "İşleniyor: $instance_id"
  aws ec2 create-tags 
    --resources "$instance_id" 
    --tags Key=LastAudit,Value=$(date +%Y-%m-%d)
done

Bu script production ortamındaki tüm çalışan instance’lara son denetim tarihini tag olarak ekliyor. Gerçek bir senaryo ama bunu çalıştırmadan önce test ortamında denemenizi öneririm.

jq ile AWS CLI Çıktısını İşlemek

--query yeterli gelmediğinde jq devreye giriyor. jq, JSON için awk gibi düşünebilirsiniz.

# jq ile instance bilgilerini formatlı yazdır
aws ec2 describe-instances 
  --output json | jq -r '.Reservations[].Instances[] | "(.InstanceId)t(.InstanceType)t(.State.Name)"'

jq ile daha karmaşık dönüşümler yapabilirsiniz. Mesela her instance için özel bir JSON çıktısı oluşturmak:

aws ec2 describe-instances 
  --output json | jq '[.Reservations[].Instances[] | {
    id: .InstanceId,
    type: .InstanceType,
    state: .State.Name,
    ip: .PrivateIpAddress,
    name: (.Tags // [] | map(select(.Key == "Name")) | first | .Value // "unnamed")
  }]'

Bu çıktıyı başka bir sisteme API üzerinden göndermek veya bir dashboard için veri kaynağı olarak kullanmak istediğinizde çok işe yarıyor.

Profil ve Bölge Yönetimi

Birden fazla AWS hesabı yönetiyorsanız profilleri ve bölgeleri CLI üzerinden yönetmek hayat kurtarır.

# Belirli bir profil ve bölge ile komut çalıştır
aws ec2 describe-instances 
  --profile production 
  --region eu-west-1 
  --query 'Reservations[*].Instances[*].[InstanceId, State.Name]' 
  --output table

# Ortam değişkenleriyle profil seçimi
export AWS_PROFILE=staging
export AWS_DEFAULT_REGION=us-east-1
aws ec2 describe-instances --query 'length(Reservations[*].Instances[*])' --output text

Birden fazla hesabı karşılaştırmalı kontrol etmek için basit bir loop:

for profile in development staging production; do
  echo "=== $profile ==="
  aws ec2 describe-instances 
    --profile "$profile" 
    --filters "Name=instance-state-name,Values=running" 
    --query 'length(Reservations[*].Instances[*])' 
    --output text
done

Bu script her ortamda kaç instance çalıştığını hızlıca gösteriyor. Sabah rutin kontrolü için idealdir.

Pagination Yönetimi

AWS API’leri genellikle sonuçları sayfalara böler. --no-paginate veya --page-size ile bunu kontrol edebilirsiniz.

# Tüm sonuçları al (pagination otomatik yönetilir)
aws ec2 describe-instances --no-paginate

# Sayfa boyutunu küçük tut (büyük ortamlarda API throttling önlemek için)
aws ec2 describe-instances --page-size 50

# Sadece ilk sayfayı al
aws ec2 describe-instances --max-items 100

Büyük S3 bucket’larında tüm nesneleri listelemek istediğinizde pagination çok önemli:

# Tüm nesneleri say, pagination'ı otomatik yönet
aws s3api list-objects-v2 
  --bucket my-huge-bucket 
  --no-paginate 
  --query 'length(Contents[*])' 
  --output text

Sık Kullanılan Komutlar için Alias Tanımlamak

Sürekli tekrar ettiğiniz uzun komutlar için bash alias’ları işinizi çok kolaylaştırır. .bashrc veya .bash_profile dosyanıza ekleyin:

# ~/.bashrc veya ~/.bash_profile

# EC2 instance listesi
alias ec2ls='aws ec2 describe-instances --query "Reservations[*].Instances[*].[InstanceId,InstanceType,State.Name,Tags[?Key==`Name`].Value|[0],PrivateIpAddress]" --output table'

# Çalışan instance sayısı
alias ec2count='aws ec2 describe-instances --filters "Name=instance-state-name,Values=running" --query "length(Reservations[*].Instances[*])" --output text'

# S3 bucket listesi
alias s3ls='aws s3api list-buckets --query "Buckets[*].[Name,CreationDate]" --output table'

Bu alias’ları tanımladıktan sonra terminalde sadece ec2ls yazarak tüm instance’larınızı görebilirsiniz.

Sonuç

AWS CLI’nin çıktı formatlama ve filtreleme özellikleri, başlangıçta öğrenme eğrisi gerektirse de zamanla vazgeçilmez hale geliyor. JMESPath sorguları yazmak ilk başta karmaşık görünüyor ama temel sözdizimini kavradıktan sonra çok güçlü şeyler yapabiliyorsunuz.

Özetlemek gerekirse pratik tavsiyelerim şunlar: --output table ile başlayın, çıktıyı göz alışkın hale getirin. Sonra --query ile küçük filtreler eklemeye başlayın. Büyük ortamlarda her zaman --filters kullanarak sunucu taraflı filtreleme yapın, gereksiz veri transferinden kaçının. Karmaşık dönüşümler için jq öğrenmeye değer. Ve sık kullandığınız komutları alias’lara alın, terminalde zaman kaybetmeyin.

Bu araçları öğrenmek için en iyi yol pratik yapmak. Kendi AWS ortamınızda bu sorguları deneyerek başlayın. AWS’nin resmi JMESPath tutorial’ı da başvurmaya değer bir kaynak. Bir süre sonra AWS konsolunu açmak yerine doğrudan CLI’ya yöneldiğinizi fark edeceksiniz, bu noktada işlerin çok daha hızlandığını göreceksiniz.

Bir yanıt yazın

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