Ansible ile çalışırken herkesin aklına ilk önce playbook’lar geliyor. YAML dosyaları, roller, şablonlar… Ama bazen tek bir komutla onlarca sunucuda bir şey yapmak istiyorsun ve playbook yazmak için ne zamanın ne de enerjinin var. İşte tam bu noktada Ansible’ın ad-hoc komut özelliği devreye giriyor. Bu yazıda ad-hoc komutları gerçek dünya senaryolarıyla ele alacağız ve neden her sysadmin’in araç kutusunda birinci sırada olması gerektiğini anlatacağım.
Ad-hoc Komut Nedir ve Neden Kullanmalısın?
Ad-hoc kelimesi Latince kökenli, “bu iş için” anlamına geliyor. Ansible bağlamında ise playbook yazmadan, doğrudan komut satırından tek seferlik işlemler yapmak demek. Düşün: 50 sunucuda aynı anda nginx servisinin durumunu kontrol etmen gerekiyor. Playbook mı yazacaksın? SSH ile tek tek mi bağlanacaksın? Tabii ki hayır.
Ad-hoc komutların temel sözdizimi şu şekilde:
ansible [host-pattern] -m [module] -a "[module-arguments]" [options]
Buradaki parametreleri açıklayalım:
- [host-pattern]: Inventory dosyandaki host grubu veya tek bir host adı
- -m: Kullanılacak Ansible modülü
- -a: Modüle geçirilecek argümanlar
- -i: Kullanılacak inventory dosyası (varsayılan
/etc/ansible/hosts) - -u: Uzak sunucularda kullanılacak kullanıcı adı
- -b: Become (sudo) ile çalıştır
- –become-user: Sudo ile geçilecek kullanıcı
- -k: SSH şifresi sor
- -K: Sudo şifresi sor
- -f: Paralel çalışacak fork sayısı (varsayılan 5)
Şimdi gerçek hayatta sıkça karşılaşılan senaryolara geçelim.
Bağlantı Testi: Ping Modülü
Herhangi bir işlem yapmadan önce sunucularının erişilebilir olup olmadığını kontrol etmek istersin. Ansible’ın ping modülü aslında ICMP ping atmaz, SSH bağlantısı kurarak Python ortamını test eder.
# Tüm sunucuları kontrol et
ansible all -m ping
# Sadece web sunucularını kontrol et
ansible webservers -m ping
# Belirli bir sunucuyu kontrol et
ansible web01.ornek.com -m ping -u deploy -i /etc/ansible/inventory/production
Çıktı şöyle görünür:
web01.ornek.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
Eğer bir sunucu erişilemezse UNREACHABLE olarak işaretlenir ve diğer sunuculara devam eder. Bu özellikle sabah ilk iş olarak tüm altyapının ayakta olup olmadığını kontrol etmek için biçilmiş kaftan.
Komut Çalıştırma: command ve shell Modülleri
En sık kullandığım modüllerin başında command ve shell geliyor. Aralarındaki fark önemli:
- command: Shell yorumlayıcısı kullanmaz, pipe (
|) ve yönlendirme (>,<) desteklemez ama daha güvenlidir - shell:
/bin/shüzerinden çalışır, pipe ve yönlendirme destekler
# Disk kullanımını kontrol et
ansible all -m command -a "df -h"
# Uptime bilgisi al
ansible all -m command -a "uptime"
# Belirli bir işlemi ara (shell gerektirir)
ansible webservers -m shell -a "ps aux | grep nginx | grep -v grep"
# Kernel versiyonunu öğren
ansible all -m command -a "uname -r"
# Son 10 log satırını getir
ansible dbservers -m shell -a "tail -10 /var/log/mysql/error.log"
Önemli not: command modülünü mümkün olduğunca tercih et. shell modülü daha güçlü ama aynı zamanda injection açıklarına daha açık.
Paket Yönetimi: apt ve yum Modülleri
Gerçek dünyada en çok kullandığım senaryo: Kritik bir güvenlik açığı çıktı ve acilen tüm sunucularda ilgili paketi güncellememiz gerekiyor. İşte tam bu noktada ad-hoc komutlar hayat kurtarıyor.
# Ubuntu/Debian sunucularda paket güncelle
ansible webservers -m apt -a "name=openssl state=latest" -b
# CentOS/RHEL sunucularda paket yükle
ansible appservers -m yum -a "name=htop state=present" -b
# Birden fazla paketi aynı anda yükle
ansible all -m apt -a "name=vim,curl,wget state=present" -b
# Paket kaldır
ansible testservers -m apt -a "name=telnet state=absent" -b
# Önce cache güncelle sonra paketi yükle
ansible webservers -m apt -a "name=nginx state=present update_cache=yes" -b
Bir keresinde production ortamında gece yarısı bir güvenlik açığı bildirim maili geldi. 30 dakika içinde 40 sunucuda libssl güncellemesi yapmam gerekiyordu. Playbook yazmak için zaman yoktu, tek satır ad-hoc komut işi halletti:
ansible all -m apt -a "name=libssl1.1 state=latest update_cache=yes" -b -f 10
-f 10 parametresiyle paralel işlem sayısını 10’a çıkardım ve tüm sunucularda güncelleme 8 dakikada tamamlandı.
Servis Yönetimi: service Modülü
Sunucularda servis yönetimi de ad-hoc komutların parladığı alanlardan biri. Deployment sonrası nginx’i yeniden başlatmak mı gerekiyor? Bir servis çökmüş mü?
# Nginx'i yeniden başlat
ansible webservers -m service -a "name=nginx state=restarted" -b
# MySQL servisini durdur
ansible dbservers -m service -a "name=mysql state=stopped" -b
# Redis'i başlat ve sistem açılışında otomatik başlamasını sağla
ansible cacheservers -m service -a "name=redis state=started enabled=yes" -b
# Servis durumunu kontrol et (systemd modülü ile)
ansible all -m systemd -a "name=sshd" -b
# Tüm gruplarda Apache'yi reload et
ansible all -m service -a "name=apache2 state=reloaded" -b
Dosya ve Dizin İşlemleri
Dosya kopyalama, izin ayarlama, dosya silme gibi işlemler için file ve copy modülleri kullanılır.
# Dosya oluştur
ansible all -m file -a "path=/tmp/test.txt state=touch"
# Dizin oluştur
ansible webservers -m file -a "path=/var/www/html/uploads state=directory mode=0755 owner=www-data group=www-data" -b
# Dosya sil
ansible all -m file -a "path=/tmp/eski_dosya.log state=absent" -b
# Yerel dosyayı uzak sunuculara kopyala
ansible webservers -m copy -a "src=/etc/nginx/nginx.conf dest=/etc/nginx/nginx.conf backup=yes" -b
# İzin değiştir
ansible all -m file -a "path=/var/log/uygulama.log mode=0640 owner=appuser group=appgroup" -b
backup=yes parametresi çok değerli. Dosyanın üzerine yazmadan önce timestamp ekleyerek yedeğini alır. Ürün ortamında yapılandırma dosyası değiştirirken bu parametreyi kullanmayı alışkanlık haline getir.
Fact Toplama: setup Modülü
Sunucular hakkında detaylı bilgi toplamak için setup modülü kullanılır. Bu modül Ansible’ın “gathering facts” adımında kullandığı modülün ta kendisi.
# Tüm fact'leri topla
ansible web01.ornek.com -m setup
# Sadece bellek bilgilerini al
ansible all -m setup -a "filter=ansible_memory_mb"
# Network arayüzlerini listele
ansible all -m setup -a "filter=ansible_interfaces"
# İşletim sistemi bilgilerini al
ansible all -m setup -a "filter=ansible_distribution*"
# Sadece IP adreslerini göster
ansible all -m setup -a "filter=ansible_default_ipv4"
Bu komutları özellikle yeni bir altyapıyı tanımak için kullanıyorum. Bir müşterinin sistemlerine ilk bağlandığımda setup modülüyle tüm sunucuların RAM, CPU, OS versiyonu gibi bilgilerini bir anda toplayabiliyorum.
Kullanıcı Yönetimi
Toplu kullanıcı yönetimi de ad-hoc komutların güçlü olduğu alanlardan biri.
# Yeni kullanıcı oluştur
ansible all -m user -a "name=deploy shell=/bin/bash groups=sudo state=present" -b
# Kullanıcı şifresi belirle
ansible all -m user -a "name=deploy password={{ 'GuvenliSifre123!' | password_hash('sha512') }}" -b
# SSH public key ekle
ansible all -m authorized_key -a "user=deploy key='{{ lookup('file', '/home/admin/.ssh/id_rsa.pub') }}' state=present" -b
# Kullanıcı sil
ansible all -m user -a "name=eski_calisan state=absent remove=yes" -b
Bir çalışan işten ayrıldığında tüm sunucularda hesabını kapatmak için tek satır yeterli. Bu işi eski yöntemle yapsan, tek tek SSH bağlansan saatlerini alır.
Cron Job Yönetimi
# Cron job ekle
ansible webservers -m cron -a "name='log temizle' hour=2 minute=0 job='/usr/local/bin/log_temizle.sh'" -b
# Cron job kaldır
ansible webservers -m cron -a "name='log temizle' state=absent" -b
# Belirli günlerde çalışan cron
ansible all -m cron -a "name='haftalik yedek' weekday=0 hour=3 minute=0 job='/opt/scripts/yedek.sh > /var/log/yedek.log 2>&1'" -b
Verbose Mod ve Hata Ayıklama
Ad-hoc komutlarda bir şeyler ters gittiğinde ne yapıyorsun? -v flag’lerini kullanıyorsun.
# Temel verbose
ansible all -m ping -v
# Daha detaylı
ansible all -m ping -vv
# Çok detaylı (SSH bağlantı detayları dahil)
ansible all -m ping -vvv
# En detaylı (genellikle gerekmiyor ama bazen işe yarıyor)
ansible all -m ping -vvvv
Ayrıca --check parametresi ile komutun gerçekten çalıştırmadan ne yapacağını görebilirsin. “Dry run” modu gibi düşün.
# Gerçekten yapmadan ne olacağını gör
ansible webservers -m apt -a "name=nginx state=absent" -b --check
# Diff ile birlikte kullan
ansible webservers -m copy -a "src=nginx.conf dest=/etc/nginx/nginx.conf" -b --check --diff
Inventory Yönetimi ve Pattern Kullanımı
Ad-hoc komutları daha etkin kullanmak için inventory pattern’larını iyi bilmek gerekiyor.
# Belirli bir grubu hariç tut
ansible 'all:!production' -m ping
# Birden fazla grup
ansible 'webservers:dbservers' -m ping
# Kesişim (her iki grupta da olan hostlar)
ansible 'webservers:&production' -m ping
# Wildcard kullanımı
ansible 'web*' -m ping
# Belirli IP aralığı
ansible '192.168.1.*' -m ping
# Tek host
ansible '192.168.1.10' -m ping -i '192.168.1.10,'
Son örnekteki virgüle dikkat et. Eğer inventory dosyası kullanmadan tek bir IP adresine bağlanmak istiyorsan IP’nin sonuna virgül eklemen gerekiyor. Bu küçük detayı bilmemek insanı çıldırtabiliyor.
Gerçek Dünya Senaryosu: Acil Güvenlik Müdahalesi
Geçen yıl yaşadığım bir senaryoyu paylaşayım. Gece 02:30’da alarm geldi, bir web sunucusunda şüpheli process var. Önce tüm web sunucularını kontrol ettim:
# Şüpheli process var mı?
ansible webservers -m shell -a "ps aux | sort -rk 3 | head -20"
# Açık portları kontrol et
ansible webservers -m shell -a "ss -tlnp"
# Son giriş yapan kullanıcılar
ansible webservers -m command -a "last -n 20"
# /tmp ve /var/tmp altında çalıştırılabilir dosya var mı?
ansible webservers -m shell -a "find /tmp /var/tmp -type f -executable 2>/dev/null"
# Beklenmedik cron job var mı?
ansible webservers -m shell -a "cat /etc/cron* 2>/dev/null; ls /var/spool/cron/crontabs/ 2>/dev/null" -b
Bu komutları art arda çalıştırarak 10 dakika içinde durumu netleştirdim. Playbook yazmakla uğraşsaydım buna yarım saat harcardım.
Çıktıları Kaydetme ve Filtreleme
Ad-hoc komut çıktılarını kaydetmek ve analiz etmek için birkaç pratik yöntem:
# Çıktıyı dosyaya kaydet
ansible all -m command -a "df -h" > /tmp/disk_durumu_$(date +%Y%m%d).txt
# Sadece başarısız olanları göster
ansible all -m ping --one-line | grep -v SUCCESS
# JSON formatında çıktı al
ansible all -m setup -a "filter=ansible_distribution" | python3 -m json.tool
# Tek satır çıktı (monitoring scriptleri için ideal)
ansible all -m ping --one-line
--one-line parametresi özellikle monitoring scriptlerinde çok işe yarıyor. Her host için tek satır çıktı veriyor ve parse etmesi çok kolay.
Performans Optimizasyonu
Çok sayıda sunucuda çalışırken bazı optimizasyonlar yapabilirsin:
# Fork sayısını artır (dikkatli kullan, ağ yükünü artırır)
ansible all -m ping -f 20
# SSH pipelining aktif et (ansible.cfg'de de yapılabilir)
ANSIBLE_SSH_PIPELINING=True ansible all -m command -a "uptime"
# Fact toplamayı devre dışı bırak (zaten kullanmıyorsan)
ansible all -m command -a "free -m" --no-gathering
# Timeout süresini ayarla
ansible all -m ping --timeout=30
ansible.cfg dosyasına da kalıcı optimizasyonlar ekleyebilirsin:
# ansible.cfg
[defaults]
forks = 20
timeout = 30
pipelining = True
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 3600
Sık Yapılan Hatalar ve Çözümleri
Hata 1: command modülü ile pipe kullanmaya çalışmak
# YANLIS - çalışmaz
ansible all -m command -a "ps aux | grep nginx"
# DOGRU - shell modülü kullan
ansible all -m shell -a "ps aux | grep nginx"
Hata 2: become olmadan root gerektiren işlem yapmak
# YANLIS - izin hatası verir
ansible all -m apt -a "name=nginx state=present"
# DOGRU
ansible all -m apt -a "name=nginx state=present" -b
Hata 3: Inventory dosyasını belirtmemek ve yanlış hostta çalışmak
# Her zaman inventory'i açıkça belirt
ansible webservers -m ping -i /etc/ansible/inventory/production
Hata 4: Özel karakterleri escape etmemek
# Tırnak işaretlerine dikkat et
ansible all -m shell -a "echo 'Merhaba Dunya' > /tmp/test.txt"
Ad-hoc Komutları Script’leştirme
Sık kullandığın ad-hoc komutları bash script’lerine dökerek hızlı erişim sağlayabilirsin:
#!/bin/bash
# hizli_kontrol.sh - Altyapı hızlı kontrol scripti
INVENTORY="/etc/ansible/inventory/production"
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
echo "=== Altyapı Kontrol Raporu - $TIMESTAMP ==="
echo -e "n--- Ping Kontrolü ---"
ansible all -m ping --one-line -i $INVENTORY
echo -e "n--- Disk Kullanımı (>80%) ---"
ansible all -m shell -a "df -h | awk 'NR>1 && int($5) > 80 {print $0}'" -i $INVENTORY
echo -e "n--- Bellek Kullanımı ---"
ansible all -m command -a "free -m" -i $INVENTORY
echo -e "n--- Yük Ortalaması ---"
ansible all -m command -a "uptime" -i $INVENTORY
echo -e "n--- Servis Durumları ---"
ansible webservers -m service -a "name=nginx" -b -i $INVENTORY
ansible dbservers -m service -a "name=mysql" -b -i $INVENTORY
Bu scripti cron ile çalıştırıp çıktısını e-posta ile alabilir veya monitoring sistemine entegre edebilirsin.
Sonuç
Ad-hoc komutlar, Ansible’ın en pratik özelliklerinden biri ve her sysadmin’in günlük iş akışına entegre etmesi gereken bir araç. Playbook yazmak için zaman ve enerji harcamadan hızlı müdahale, toplu değişiklik ve sistem durumu kontrolü yapabiliyorsun.
Şunu unutma: Ad-hoc komutlar güçlü ama aynı zamanda dikkat isteyen araçlar. ansible all ile başlayan bir komut yazarken iki kere düşün, bir kere çalıştır. Production ortamında yanlış bir komut tüm altyapını etkileyebilir. Her zaman önce --check ile test et, özellikle değişiklik yapan komutlarda.
Zamanla hangi komutları sık kullandığını fark edeceksin. Onları bir cheatsheet dosyasına ya da bir script’e dökerek erişimini kolaylaştır. Ben şu an elimde 30’dan fazla hazır ad-hoc komut var ve bir şeylere ihtiyaç duyduğumda saniyeler içinde çalıştırabiliyorum.
Ansible’ı gerçekten verimli kullanmak istiyorsan ad-hoc komutlarla başla, altyapını tanı, sonra playbook’larla ilerle. Bu sıra hem öğrenmeyi kolaylaştırıyor hem de işleri gerçekten hızlandırıyor.