Azure CLI ile Kaynak Grubu Yönetimi
Bulut altyapısını yönetirken en çok zaman kaybettiğimiz yerlerden biri kaynak organizasyonu. Azure’da her şeyin bir kaynak grubuna bağlı olduğunu düşünürsek, bu yapıyı doğru kurmak ve yönetmek kritik önem taşıyor. Azure Portal üzerinden tıklaya tıklaya iş yapmak başlangıçta kolay görünse de ekip büyüdükçe, ortam sayısı arttıkça ve otomasyon ihtiyacı doğdukça komut satırı kaçınılmaz hale geliyor. Bu yazıda Azure CLI kullanarak kaynak gruplarını nasıl etkin biçimde yöneteceğimizi, gerçek dünya senaryolarıyla birlikte inceleyeceğiz.
Azure CLI Kurulumu ve Temel Hazırlık
Başlamadan önce ortamımızın hazır olduğundan emin olalım. Azure CLI’yı birkaç farklı yolla kurabilirsiniz ama ben doğrudan paket yöneticisi üzerinden gitmeyi tercih ediyorum.
Linux (Ubuntu/Debian) için:
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
macOS için:
brew update && brew install azure-cli
Windows için PowerShell:
winget install -e --id Microsoft.AzureCLI
Kurulum tamamlandıktan sonra versiyonu kontrol edelim ve giriş yapalım:
az --version
az login
az login komutu tarayıcı açarak Microsoft hesabınızla giriş yapmanızı istiyor. Headless ortamlarda, yani sunucu üzerinde çalışırken device code akışını kullanmanız gerekiyor:
az login --use-device-code
Birden fazla subscription’ınız varsa aktif olanı belirleyin:
# Mevcut subscription'ları listele
az account list --output table
# Belirli bir subscription'ı aktif yap
az account set --subscription "Subscription-ID-veya-Adi"
# Aktif subscription'ı doğrula
az account show
Bu adımı atlamayın. Yanlış subscription’da çalışmak, kaynakların beklenmedik yerlerde oluşmasına neden olur ve faturanızda sürprizler yaşarsınız.
Kaynak Grubu Nedir ve Neden Önemlidir?
Azure’da kaynak grubu, ilgili kaynakları bir arada tutan mantıksal bir konteyner. Sanal makineler, storage account’lar, ağ bileşenleri, database’ler, bunların hepsi mutlaka bir kaynak grubuna ait olmak zorunda. Kaynak grubunu silerseniz içindeki tüm kaynaklar da gidiyor. Bu hem güçlü hem de tehlikeli bir özellik.
İyi bir kaynak grubu stratejisi şu prensiplere dayanır:
- Yaşam döngüsü birliği: Birlikte oluşturulan ve birlikte silinecek kaynakları aynı grupta toplayın
- Ortam ayrımı: dev, staging, prod ortamlarını ayrı gruplarda tutun
- Uygulama bazlı gruplama: Farklı uygulamaları farklı gruplarda izole edin
- Bölge dikkati: Kaynak grubu bölgesi, metadata’nın tutulduğu yeri belirler; kaynaklar farklı bölgelerde olabilir
Kaynak Grubu Oluşturma
En basit haliyle kaynak grubu oluşturmak tek satır:
az group create --name rg-myapp-prod --location westeurope
Ama üretim ortamında çalışıyorsanız mutlaka tag ekleyin. Tag’ler olmadan maliyet takibi ve kaynak yönetimi cehenneme dönüyor:
az group create
--name rg-myapp-prod
--location westeurope
--tags
Environment=Production
Application=MyApp
Owner=devops-team
CostCenter=CC-1234
CreatedBy=ali.yilmaz
CreatedDate=2024-01-15
Buradaki --tags parametresi key=value formatında birden fazla değer alıyor. Tag’leri sonradan da ekleyebilirsiniz ama en başından doğru kurmak size büyük zaman kazandırır.
Location değerlerini görmek için:
az account list-locations --output table
Türkiye’deki veri merkezi için germanywestcentral veya swedencentral çoğu zaman tercih edilen lokasyonlar. westeurope Amsterdam merkezli.
Kaynak Gruplarını Listeleme ve Sorgulama
Aboneliğinizdeki tüm kaynak gruplarını görmek için:
# Tüm kaynak gruplarını listele
az group list --output table
# JSON formatında detaylı çıktı
az group list --output json
# Sadece belirli lokasyondaki grupları filtrele
az group list --query "[?location=='westeurope']" --output table
# Belirli tag'e sahip grupları filtrele
az group list --query "[?tags.Environment=='Production']" --output table
--query parametresi JMESPath kullanıyor ve son derece güçlü. Büyük ortamlarda yüzlerce kaynak grubu olabiliyor, bu yüzden filtreleme kritik:
# Sadece isim ve lokasyon kolonlarını göster
az group list --query "[].{Name:name, Location:location, State:properties.provisioningState}" --output table
# İsme göre arama
az group list --query "[?contains(name, 'prod')]" --output table
Belirli bir kaynak grubunun detaylarını görmek için:
az group show --name rg-myapp-prod
# Sadece kaynak grubu ID'sini al (script'lerde kullanışlı)
az group show --name rg-myapp-prod --query id --output tsv
Tag Yönetimi
Tag yönetimi, büyük Azure ortamlarında maliyet takibi ve kaynak yönetimi için can simidi. Sonradan tag eklemek veya güncellemek için:
# Mevcut tag'lere yeni tag ekle (var olanları korur)
az group update
--name rg-myapp-prod
--set tags.LastUpdated=2024-01-20
# Tüm tag'leri değiştir (dikkatli kullanın, eskiler silinir)
az group update
--name rg-myapp-prod
--tags Environment=Production Application=MyApp Owner=devops-team
# Belirli bir tag'i sil
az group update
--name rg-myapp-prod
--remove tags.OldTag
Gerçek dünyada sık karşılaşılan bir senaryo: Onlarca kaynak grubuna toplu tag eklemeniz gerekiyor. Script yazalım:
#!/bin/bash
# Tüm Production kaynak gruplarına CostCenter tag'i ekle
GROUPS=$(az group list --query "[?tags.Environment=='Production'].name" --output tsv)
for group in $GROUPS; do
echo "Updating: $group"
az group update
--name "$group"
--set tags.CostCenter=CC-9999
--output none
echo "Done: $group"
done
echo "Tüm gruplar güncellendi."
Kaynak Grubu İçindeki Kaynakları Yönetme
Kaynak grubu içinde ne olduğunu görmek, sorun giderme ve maliyet analizi için önemli:
# Gruptaki tüm kaynakları listele
az resource list --resource-group rg-myapp-prod --output table
# Sadece belirli tipte kaynakları filtrele
az resource list
--resource-group rg-myapp-prod
--resource-type "Microsoft.Compute/virtualMachines"
--output table
# Kaynakları tag'e göre filtrele
az resource list
--resource-group rg-myapp-prod
--query "[?tags.Tier=='Web']"
--output table
Kaynakları başka bir kaynak grubuna taşımak da mümkün. Bu özelliği dikkatli kullanmak gerekiyor çünkü bazı kaynak tipleri taşınamıyor veya taşıma sırasında kısa süreli kesinti yaşanabiliyor:
# Taşımadan önce taşınabilirlik kontrolü yap
az resource invoke-action
--action validateMoveResources
--ids "/subscriptions/SUB-ID/resourceGroups/rg-source"
--request-body '{"resources": ["/subscriptions/SUB-ID/resourceGroups/rg-source/providers/Microsoft.Compute/virtualMachines/my-vm"], "targetResourceGroup": "/subscriptions/SUB-ID/resourceGroups/rg-target"}'
# Kaynağı taşı
az resource move
--destination-group rg-myapp-prod-new
--ids "/subscriptions/SUB-ID/resourceGroups/rg-myapp-prod/providers/Microsoft.Compute/virtualMachines/my-vm"
Kilit (Lock) Mekanizması
Üretim ortamında kritik kaynak gruplarını yanlışlıkla silmekten korumak için lock kullanmak şart. Bu özelliği kullanmayan ortamlarda er ya da geç kazayla silme olayı yaşanıyor:
# ReadOnly lock ekle (okuma izni var, yazma/silme yok)
az lock create
--name "prod-readonly-lock"
--resource-group rg-myapp-prod
--lock-type ReadOnly
--notes "Production ortamı - değişiklik için Change Management süreci gerekli"
# CanNotDelete lock ekle (okuma/yazma var, silme yok)
az lock create
--name "prod-nodelete-lock"
--resource-group rg-myapp-prod
--lock-type CanNotDelete
--notes "Bu grubu silmeden önce oncall ekibine danışın"
# Mevcut lock'ları görüntüle
az lock list --resource-group rg-myapp-prod --output table
# Lock kaldır
az lock delete
--name "prod-nodelete-lock"
--resource-group rg-myapp-prod
CanNotDelete çoğu durumda daha mantıklı seçenek. ReadOnly koyarsanız, Azure Resource Manager bazı okuma operasyonlarını bile engelleyebiliyor, bu da beklenmedik sorunlara yol açıyor.
Deployment ve ARM Template Yönetimi
Kaynak grupları ARM template veya Bicep ile birlikte kullanıldığında Infrastructure as Code’un temelini oluşturuyor. CLI üzerinden deployment yönetmek son derece kullanışlı:
# ARM template ile kaynak grubu ve kaynakları oluştur
az deployment group create
--resource-group rg-myapp-prod
--template-file ./infrastructure/main.json
--parameters ./infrastructure/prod.parameters.json
# Bicep template kullan
az deployment group create
--resource-group rg-myapp-prod
--template-file ./infrastructure/main.bicep
--parameters environment=prod appName=myapp
# What-if ile değişiklikleri önce görüntüle (prod için zorunlu alışkanlık)
az deployment group what-if
--resource-group rg-myapp-prod
--template-file ./infrastructure/main.bicep
--parameters environment=prod
# Deployment geçmişini listele
az deployment group list
--resource-group rg-myapp-prod
--output table
# Belirli bir deployment'ın detaylarını gör
az deployment group show
--resource-group rg-myapp-prod
--name "main-20240115-143022"
Gerçek Dünya Senaryosu: Çok Ortamlı Yapı Kurulumu
Diyelim ki yeni bir mikroservis projesi başlatıyorsunuz ve dev, staging, prod ortamları kurmanız gerekiyor. Her ortam için ayrı kaynak grupları, doğru tag’ler ve lock’lar ile bunu otomatize eden bir script yazalım:
#!/bin/bash
# multi-env-setup.sh
# Çok ortamlı Azure altyapısı kurulum scripti
set -e # Hata durumunda scripti durdur
# Değişkenler
APP_NAME="payment-service"
LOCATION="westeurope"
OWNER="platform-team"
COST_CENTER="CC-2024-PS"
ENVIRONMENTS=("dev" "staging" "prod")
# Renk kodları log için
RED='33[0;31m'
GREEN='33[0;32m'
YELLOW='33[1;33m'
NC='33[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
for ENV in "${ENVIRONMENTS[@]}"; do
RG_NAME="rg-${APP_NAME}-${ENV}"
log_info "Kaynak grubu oluşturuluyor: $RG_NAME"
az group create
--name "$RG_NAME"
--location "$LOCATION"
--tags
Environment="$ENV"
Application="$APP_NAME"
Owner="$OWNER"
CostCenter="$COST_CENTER"
CreatedDate="$(date +%Y-%m-%d)"
ManagedBy=cli-automation
--output none
log_info "$RG_NAME oluşturuldu."
# Sadece prod ortamına CanNotDelete lock ekle
if [ "$ENV" == "prod" ]; then
log_warn "Production lock ekleniyor..."
az lock create
--name "${RG_NAME}-nodelete"
--resource-group "$RG_NAME"
--lock-type CanNotDelete
--notes "Production kaynak grubu - silmeden önce oncall onayı gerekli"
--output none
log_info "Production lock eklendi."
fi
echo "---"
done
log_info "Tüm ortamlar başarıyla kuruldu!"
log_info "Oluşturulan gruplar:"
az group list
--query "[?tags.Application=='${APP_NAME}'].{Name:name, Location:location, Env:tags.Environment}"
--output table
Bu script birkaç saniye içinde tutarlı, doğru etiketlenmiş ve güvenli bir çok ortam yapısı kuruyor.
Kaynak Grubu Silme
Kaynak grubu silmek geri alınamaz bir operasyon. İçindeki tüm kaynaklar, VM’ler, disk’ler, network bileşenleri, database’ler, hepsi gidiyor. Bu yüzden dikkatli olmak gerekiyor.
# Kaynak grubunu sil (onay ister)
az group delete --name rg-myapp-dev
# Onay sorma (script'lerde kullanışlı, ama tehlikeli!)
az group delete --name rg-myapp-dev --yes
# No-wait ile silmeyi başlat ve beklemeden devam et
az group delete --name rg-myapp-dev --yes --no-wait
# Silmeden önce içeriği kontrol et
az resource list --resource-group rg-myapp-dev --output table
echo "Bu kaynaklar SİLİNECEK. Emin misiniz?"
read -p "Devam etmek için 'evet' yazın: " CONFIRM
if [ "$CONFIRM" == "evet" ]; then
az group delete --name rg-myapp-dev --yes
else
echo "İptal edildi."
fi
Özellikle otomasyonda --yes flag’ini kullanmadan önce script’inizin doğru kaynak grubunu hedef aldığından %100 emin olun. Bu konuda acı deneyimleri olan sysadmin sayısı az değil.
RBAC ile Kaynak Grubu Erişim Yönetimi
Kaynak grubu düzeyinde rol atamak, ekip üyelerine minimal yetki prensibiyle erişim vermek için ideal:
# Kullanıcıya Reader rolü ver (sadece görüntüleme)
az role assignment create
--assignee [email protected]
--role Reader
--scope "/subscriptions/SUB-ID/resourceGroups/rg-myapp-prod"
# Servis principal'a Contributor rolü ver
az role assignment create
--assignee "SERVICE-PRINCIPAL-OBJECT-ID"
--role Contributor
--resource-group rg-myapp-dev
# Kaynak grubu üzerindeki mevcut rol atamalarını listele
az role assignment list
--resource-group rg-myapp-prod
--output table
# Rol atamasını kaldır
az role assignment delete
--assignee [email protected]
--role Reader
--resource-group rg-myapp-prod
Maliyet Yönetimi için Kaynak Grubu Sorgulama
Azure Cost Management CLI entegrasyonu ile kaynak grubu bazlı maliyet takibi yapabilirsiniz:
# Belirli kaynak grubunun aylık maliyetini sorgula
az costmanagement query
--type Usage
--scope "/subscriptions/SUB-ID"
--dataset-filter "{"and":[{"dimensions":{"name":"ResourceGroup","operator":"In","values":["rg-myapp-prod"]}}]}"
--timeframe MonthToDate
# Tag'e göre maliyet analizi için kaynak grubu listesi
az group list
--query "[?tags.CostCenter=='CC-2024-PS'].name"
--output tsv
Faydalı İpuçları ve Kaçınılması Gereken Hatalar
Günlük kullanımda işinizi kolaylaştıracak bazı pratik bilgiler:
- Output formatı seçimi:
--output tableinsan okumak için,--output jsonscript parse etmek için,--output tsvdeğişkenlere atamak için idealdir --output none: Uzun script’lerde gereksiz çıktıyı bastırmak için kullanın, log okunabilirliğini artırır- Query performansı: Çok sayıda kaynak grubunda
az group listyavaşlayabilir,--subscriptionile scope’u daraltın - Paralel işlemler:
--no-waitflag’i uzun süren operasyonlarda script’i bloke olmaktan kurtarır - Environment variable:
AZURE_DEFAULTS_GROUPveAZURE_DEFAULTS_LOCATIONortam değişkenlerini set ederek her komuta--resource-groupyazmaktan kurtulabilirsiniz
# Default değerleri ayarla
az configure --defaults group=rg-myapp-dev location=westeurope
# Artık --resource-group yazmana gerek yok
az resource list --output table
# Default değerleri temizle
az configure --defaults group='' location=''
Sık yapılan hataların başında naming convention’a uymamak geliyor. rg- prefix’i, sonra uygulama adı, sonra ortam şeklinde tutarlı bir isimlendirme hem görsel düzeni sağlıyor hem de contains sorgularında işinizi kolaylaştırıyor.
Bir diğer önemli nokta: Kaynak grubunu bir bölgede oluşturup kaynakları farklı bölgelerde yaratabilirsiniz, ama kaynak grubunun bölgesi metadata’nın saklandığı yeri belirliyor. Kaynak grubu bölgesi down olursa Portal’dan kaynaklarınıza erişemeyebilirsiniz, kaynakların kendisi çalışmaya devam eder ama yönetim katmanı etkilenir.
Sonuç
Azure CLI ile kaynak grubu yönetimi, bulut altyapısının bel kemiğini oluşturuyor. Portal üzerinden da aynı işlemleri yapabilirsiniz ama CLI’nın gücü tekrarlanabilirlik ve otomasyonda ortaya çıkıyor. Bir script yazıyorsunuz, test ortamında deniyor, onaylıyorsunuz ve aynısını prod’da çalıştırıyorsunuz. İnsan hatasını minimuma indiren bu yaklaşım, ekip büyüdükçe ve ortam sayısı arttıkça değerini daha da artırıyor.
Pratik öneriler olarak şunları vurgulayayım: Tag’leri en başından ekleyin, silinmesini istemediğiniz her şeye lock koyun, what-if komutunu prod ortamı değişikliklerinde alışkanlık haline getirin ve tüm CLI komutlarınızı versiyon kontrollü script’lere alın. Bu alışkanlıklar başlangıçta ekstra efor gibi görünse de ilerleyen süreçte sizi hem maliyet sürprizlerinden hem de “yanlışlıkla sildim” krizlerinden koruyor.
Azure CLI sürekli güncelleniyor, yeni komutlar ve özellikler ekleniyor. az upgrade ile CLI’yı güncel tutmayı ve az --help ile az group --help komutlarını aktif kullanmayı alışkanlık edinin. Dokümantasyon bazen eksik kalabiliyor ama --help çıktısı genellikle ihtiyacınız olan her şeyi içeriyor.
