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.
