CLI ve jq ile Bulut Kaynaklarını Betikleme
Bulut sağlayıcısı CLI'larını idempotent biçimde yönetin ve kaynakları hazırlamak ya da kaldırmak için JSON yanıtlarını ayrıştırın.
CLI ve jq ile Bulut Kaynaklarını Betikleme, CoddyKit'te ücretsiz bir DevOps Bootcamp dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, DevOps Bootcamp öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. DevOps Bootcamp kursu toplamda 4 dersten oluşur.
Tekrarlı Çalıştırılabilir Bulut Betikleri Neden Önemlidir
C2 düzeyinde bulut betikleri yazmak, düğmelere tıklamakla ilgili değildir; yinelenen kaynaklar oluşturmadan veya ikinci çalıştırmada başarısız olmadan birden çok kez güvenle çalışabilen kod yazmakla ilgilidir.
Tekrarlı çalıştırılabilir bir betik, oluşturmadan önce bir kaynağın zaten var olup olmadığını denetler. Bu, güvenilir altyapı otomasyonunun temel taşıdır.
- Bulut komut satırı araçları (AWS, GCP, Azure) JSON döndürür; bu çıktıyı ayrıştırmak çok önemlidir.
jq, kabuk betiklerinden alınan JSON'u parçalamak, süzmek ve dönüştürmek için standart Unix aracıdır.- Komut satırı aracı + jq + koşullu mantığı birleştirmek, sağlam ve tekrarlanabilir sağlama betikleri yazmanızı sağlar.
Bu ders boyunca, doğrudan gcloud ve az araçlarına aktarılabilen düzenleri kullanarak AWS CLI'yi temel alıp S3 kovaları, EC2 örnekleri ve IAM rolleri sağlayacaksınız.
Bulut Komut Satırı Araçlarını Kurma ve Doğrulama
Betik yazmaya başlamadan önce doğru araçların mevcut olduğunu doğrulayın. Ortamlar arasındaki farklılıkları önlemek için CI'da sürümleri her zaman sabitleyin.
Aşağıdaki kod parçası AWS CLI v2'yi, jq'yu ve GCP SDK'yı denetler; yalnızca eksik olanları kurar. Bu düzen, yeni sanal makineler veya konteynerler için hazırlama betiklerinde kullanılabilir.
#!/usr/bin/env bash
set -euo pipefail
check_or_install() {
local cmd="$1"
local install_cmd="$2"
if ! command -v "$cmd" &>/dev/null; then
echo "[INFO] $cmd not found — installing..."
eval "$install_cmd"
else
echo "[OK] $cmd $("$cmd" --version 2>&1 | head -1)"
fi
}
# AWS CLI v2
check_or_install aws \
'curl -fsSL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscliv2.zip && unzip -q /tmp/awscliv2.zip -d /tmp && sudo /tmp/aws/install'
# jq
check_or_install jq \
'sudo apt-get install -y jq 2>/dev/null || sudo yum install -y jq'
# gcloud (optional)
check_or_install gcloud \
'echo "Install gcloud SDK manually from https://cloud.google.com/sdk"'
echo "All prerequisites satisfied."jq ile Mevcut Kaynakları Sorgulama
Her tekrarlı çalıştırılabilir betiğin ilk adımı bir okuma işlemidir: API'ye kaynağın zaten var olup olmadığını sorar, ardından buna göre dallanırsınız.
AWS CLI her zaman JSON döndürür. jq tam olarak ihtiyacınız olan alanı çıkarmanızı sağlar:
jq -r '.Buckets[].Name'— ham dize çıktısı; satır başına bir kova adı.jq -e— ifadenullveyafalseürettiğinde 1 çıkış koduyla sonlanır; bu nedenleifkorumaları için idealdir.jq '.[] | select(.Name == env.BUCKET)'—envaracılığıyla bir kabuk değişkeni kullanarak süzme yapar.
Aşağıdaki kod parçası tüm S3 kovalarını listeler ve hedef kovanın zaten var olup olmadığını denetler.
#!/usr/bin/env bash
set -euo pipefail
BUCKET="my-devops-artifacts-$(date +%Y%m)"
echo "Fetching existing S3 buckets..."
EXISTING=$(aws s3api list-buckets --output json)
# Extract names as newline-separated list
echo "$EXISTING" | jq -r '.Buckets[].Name'
# Check if target bucket exists
if echo "$EXISTING" | jq -e --arg b "$BUCKET" '.Buckets[] | select(.Name == $b)' > /dev/null 2>&1; then
echo "[EXISTS] Bucket $BUCKET already present — skipping creation."
else
echo "[MISSING] Bucket $BUCKET not found — will create."
fiTekrarlı Çalıştırılabilir S3 Kovası Oluşturma
Varlık denetimi hazır olduğuna göre oluşturma işlemini bir koşul korumasına alın. İyi yapılandırılmış bir bulut işlevi şu düzeni izler:
- API'den geçerli durumu okuyun.
- İstenen durumu gerçek durumla karşılaştırın.
- Yalnızca fark varsa işlem yapın.
--create-bucket-configuration seçeneğine dikkat edin; us-east-1 dışındaki tüm bölgeler için gereklidir. Bölgeyi betiğin içine sabitlemek, AWS_DEFAULT_REGION ayarlanmamış olduğunda oluşabilecek sessiz hataları önler.
#!/usr/bin/env bash
set -euo pipefail
REGION="eu-west-1"
BUCKET="my-devops-artifacts-$(date +%Y%m)"
ensure_bucket() {
local bucket="$1"
local region="$2"
local existing
existing=$(aws s3api list-buckets --query 'Buckets[].Name' --output json)
if echo "$existing" | jq -e --arg b "$bucket" 'index($b) != null' > /dev/null 2>&1; then
echo "[SKIP] Bucket $bucket already exists."
return 0
fi
echo "[CREATE] Creating bucket $bucket in $region..."
aws s3api create-bucket \
--bucket "$bucket" \
--region "$region" \
--create-bucket-configuration LocationConstraint="$region"
# Enable versioning immediately after creation
aws s3api put-bucket-versioning \
--bucket "$bucket" \
--versioning-configuration Status=Enabled
echo "[DONE] Bucket $bucket created with versioning enabled."
}
ensure_bucket "$BUCKET" "$REGION"İç İçe JSON'u Ayrıştırma: EC2 Örnek Durumu
EC2 yanıtları derin biçimde iç içedir. jq yol boyunca gezinme ve --query (AWS CLI'ye özgü JMESPath) yöntemlerinin ikisi de işe yarar; ancak karmaşık mantık için jq daha güçlüdür.
EC2 için temel jq kalıpları:
.Reservations[].Instances[]— iki dizili yapıyı düzleştirir.select(.State.Name == "running")— duruma göre süzer..Tags[] | select(.Key == "Name") | .Value— bir etiket değerini çıkarır.
Aşağıdaki kod parçası, Name etiketiyle çalışan bir örneği bulur ve örneğin ID değerini ve özel IP adresini döndürür.
#!/usr/bin/env bash
set -euo pipefail
INSTANCE_NAME="web-server-prod"
RESULT=$(aws ec2 describe-instances \
--filters \
"Name=tag:Name,Values=${INSTANCE_NAME}" \
"Name=instance-state-name,Values=running" \
--output json)
# Extract instance ID and private IP using jq
INSTANCE_ID=$(echo "$RESULT" | jq -r \
'.Reservations[].Instances[] | .InstanceId')
PRIVATE_IP=$(echo "$RESULT" | jq -r \
'.Reservations[].Instances[] | .PrivateIpAddress')
if [[ -z "$INSTANCE_ID" ]]; then
echo "[WARN] No running instance named '$INSTANCE_NAME' found."
exit 1
fi
echo "Instance ID : $INSTANCE_ID"
echo "Private IP : $PRIVATE_IP"Tekrarlı Çalıştırılabilir IAM Rolü Sağlama
IAM kaynakları küreseldir ve çoğaltılmamalıdır. AWS, zaten var olan bir rolü oluşturmaya çalıştığınızda belirli bir hata kodu olan EntityAlreadyExists kodunu döndürür. Bu kodu yakalamak, IAM ile geniş ölçekte çalışırken önceden kontrol amaçlı listeleme çağrısı yapmaktan daha temiz bir tekrarlı çalıştırılabilirlik düzenidir.
Aşağıdaki betik şunları gösterir:
set -enedeniyle işlemin durmasını önlemek için|| trueile komut satırı aracının çıkış kodunu yakalamak.- AWS'nin standart hata akışına yazdığı hata iletisi JSON'unu işlem ikamesi kullanarak ayrıştırmak.
- Bir ilkeyi yalnızca daha önce iliştirilmemişse iliştirmek.
#!/usr/bin/env bash
set -euo pipefail
ROLE_NAME="DevOpsDeployRole"
POLICY_ARN="arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
TRUST_POLICY='{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "ec2.amazonaws.com" },
"Action": "sts:AssumeRole"
}]
}'
# Attempt creation; ignore EntityAlreadyExists
CREATE_OUTPUT=$(aws iam create-role \
--role-name "$ROLE_NAME" \
--assume-role-policy-document "$TRUST_POLICY" \
--output json 2>&1) || {
if echo "$CREATE_OUTPUT" | grep -q 'EntityAlreadyExists'; then
echo "[SKIP] Role $ROLE_NAME already exists."
else
echo "[ERROR] Unexpected error: $CREATE_OUTPUT" >&2
exit 1
fi
}
# Attach policy (attach-role-policy is idempotent by default)
aws iam attach-role-policy \
--role-name "$ROLE_NAME" \
--policy-arn "$POLICY_ARN"
echo "[OK] Role $ROLE_NAME ready with policy $POLICY_ARN."jq İleri Düzey: Dönüştürmeler, Eşlemeler ve toentries
Gerçek altyapı yanıtları düzinelerce alan içerir. jq dönüşümleri, çıktıyı sonraki araçlar, günlükler veya yapılandırma dosyaları için yeniden biçimlendirmenizi sağlar.
İleri düzey temel kalıplar:
map(select(...))— dizi sarmalayıcısını kaybetmeden bir diziyi süzer.to_entries | map(select(.value != null))— yapılandırmaya yazmadan önce boş değerli alanları kaldırır.[.[] | {id: .InstanceId, ip: .PrivateIpAddress}]— verileri yeni bir biçime dönüştürür.@csv,@tsv,@base64— yerleşik biçim dönüştürücüleridir.
Aşağıdaki kod parçası çalışan tüm örnekleri çıkarır ve bir TSV envanter dosyası yazar.
#!/usr/bin/env bash
set -euo pipefail
OUTPUT_FILE="/tmp/ec2_inventory.tsv"
aws ec2 describe-instances \
--filters "Name=instance-state-name,Values=running" \
--output json \
| jq -r '
["InstanceId", "Name", "PrivateIp", "Type", "AZ"],
[
.Reservations[].Instances[] | [
.InstanceId,
(.Tags // [] | map(select(.Key == "Name")) | .[0].Value // "(none)"),
(.PrivateIpAddress // "N/A"),
.InstanceType,
.Placement.AvailabilityZone
]
][]
| @tsv' > "$OUTPUT_FILE"
echo "Inventory written to $OUTPUT_FILE:"
column -t "$OUTPUT_FILE"Eşzamansız İşlemleri Bekleme: jq ile Yoklama
Bulut işlemleri eşzamansızdır. Bir EC2 örneği oluşturmak, işlemi pending durumuyla hemen döndürür. Güvenilir betikler devam etmeden önce istenen duruma ulaşılana kadar yoklama yapmalıdır.
Aşağıdaki düzen, üstel geri çekilmeli bir until döngüsü kullanır. AWS CLI ayrıca wait alt komutları da sağlar (örneğin aws ec2 wait instance-running); ancak yoklamayı elle yazmak, özel zaman aşımı denetimi ve daha ayrıntılı günlükleme olanağı verir.
#!/usr/bin/env bash
set -euo pipefail
INSTANCE_ID="i-0abcdef1234567890"
MAX_WAIT=300 # seconds
INTERVAL=10
ELAPSED=0
echo "Waiting for instance $INSTANCE_ID to reach 'running' state..."
while true; do
STATE=$(aws ec2 describe-instances \
--instance-ids "$INSTANCE_ID" \
--output json \
| jq -r '.Reservations[0].Instances[0].State.Name')
echo " [$(date +%T)] state = $STATE"
[[ "$STATE" == "running" ]] && break
if [[ "$STATE" == "terminated" || "$STATE" == "shutting-down" ]]; then
echo "[FATAL] Instance entered terminal state: $STATE" >&2
exit 1
fi
if (( ELAPSED >= MAX_WAIT )); then
echo "[TIMEOUT] Instance did not reach 'running' after ${MAX_WAIT}s." >&2
exit 1
fi
sleep "$INTERVAL"
(( ELAPSED += INTERVAL ))
done
echo "[OK] Instance $INSTANCE_ID is running."Çok Bulutlu Düzen: GCP ve Azure Karşılıkları
Tekrarlı çalıştırılabilir okuma-sonra-eyleme geçme düzeni, diğer bulut komut satırı araçlarına da doğrudan aktarılabilir. Hem gcloud hem de az JSON döndürür ve süzmeyi destekler:
- GCP:
gcloud ... --format='json'— AWS'de olduğu gibi doğrudanjq'ya yönlendirin. Betiklerde istemleri bastırmak içingcloud ... --quietkullanın. - Azure:
az ... --output json— aynı düzen.az group existsdüz bir doğru/yanlış dizesi (true/false) döndürür; basit durumlarda jq kullanma gereğini ortadan kaldırır.
Aşağıdaki kod parçası, aynı koşul koruması düzenini kullanarak Azure'da tekrarlı çalıştırılabilir kaynak grubu oluşturmayı ve GCP'de GCS kovası oluşturmayı yan yana gösterir.
#!/usr/bin/env bash
set -euo pipefail
# --- Azure: idempotent resource group ---
RG="devops-rg"
LOCATION="westeurope"
if [[ $(az group exists --name "$RG") == "true" ]]; then
echo "[SKIP] Azure resource group $RG already exists."
else
echo "[CREATE] Creating Azure resource group $RG..."
az group create --name "$RG" --location "$LOCATION" --output json \
| jq '{name: .name, location: .location, provisioningState: .properties.provisioningState}'
fi
# --- GCP: idempotent GCS bucket ---
GCS_BUCKET="gs://devops-artifacts-prod"
PROJECT="my-gcp-project"
if gcloud storage buckets describe "$GCS_BUCKET" \
--project="$PROJECT" --format='value(name)' &>/dev/null; then
echo "[SKIP] GCS bucket $GCS_BUCKET already exists."
else
echo "[CREATE] Creating GCS bucket $GCS_BUCKET..."
gcloud storage buckets create "$GCS_BUCKET" \
--project="$PROJECT" \
--location=EU \
--uniform-bucket-level-access
fiSökme: Kaynakları Güvenle Yok Etme
Yok etme betikleri, oluşturma betikleri kadar önemlidir. Güvenli bir sökme işlemi:
- Herhangi bir şeyi silmeden önce kaynakları listeler ve insan incelemesi için bir özet yazdırır.
- İşletmecilerin planı uygulamadan doğrulayabilmesi için bir
--dry-runseçeneğini kabul eder. - Silme işlemlerini doğru bağımlılık sırasıyla gerçekleştirir (örneğin güvenlik gruplarını silmeden önce örnekleri sonlandırır).
Aşağıdaki kod parçası, deneme çalıştırması korumasıyla Env=staging etiketi taşıyan tüm EC2 örneklerini sonlandırır.
#!/usr/bin/env bash
set -euo pipefail
DRY_RUN="${1:-}"
echo "Finding staging EC2 instances..."
INSTANCE_IDS=$(aws ec2 describe-instances \
--filters \
"Name=tag:Env,Values=staging" \
"Name=instance-state-name,Values=running,stopped" \
--output json \
| jq -r '[.Reservations[].Instances[].InstanceId] | @sh')
if [[ -z "$INSTANCE_IDS" ]]; then
echo "[INFO] No staging instances found. Nothing to do."
exit 0
fi
echo "Instances to terminate: $INSTANCE_IDS"
if [[ "$DRY_RUN" == "--dry-run" ]]; then
echo "[DRY-RUN] No changes made."
exit 0
fi
read -rp "Terminate these instances? [yes/N]: " CONFIRM
[[ "$CONFIRM" != "yes" ]] && { echo "Aborted."; exit 0; }
# shellcheck disable=SC2086
aws ec2 terminate-instances --instance-ids $INSTANCE_IDS --output json \
| jq '.TerminatingInstances[] | {id: .InstanceId, state: .CurrentState.Name}'
echo "[DONE] Termination initiated."Uçtan Uca: Tekrar Çalıştırılabilir Altyapı Başlatma Betiği
Hepsini bir araya getirelim: üretim düzeyinde bir başlatma betiği, birden çok kaynağı doğru sırayla koordine eder, yeniden çalıştırıldığında da aynı sonucu verir ve bir sürekli tümleştirme sisteminin ayrıştırabileceği yapılandırılmış günlükler üretir.
Gösterilen temel uygulamalar:
- Yapılandırılmış günlük kaydı,
[INFO],[WARN],[ERROR]ön eklerini ekleyen birlog()yardımcısı aracılığıyla yapılır. - Durum dosyası — oluşturulan kaynak kimliklerini bir JSON durum dosyasına yazın; böylece sonraki çalıştırmalar ve kaldırma betikleri aynı başvuruları paylaşır.
- Hata yakalama mekanizması —
trap, beklenmedik çıkışları yakalar ve başarısız olan satırın numarasını bildirir.
#!/usr/bin/env bash
set -euo pipefail
STATE_FILE="/tmp/infra_state.json"
REGION="eu-west-1"
BUCKET="devops-bootstrap-$(date +%Y%m)"
ROLE="BootstrapRole"
log() { echo "[$(date -u +%T)] [$1] ${*:2}"; }
trap 'log ERROR "Script failed at line $LINENO"' ERR
# Initialize state
[[ -f "$STATE_FILE" ]] || echo '{}' > "$STATE_FILE"
# --- Step 1: S3 bucket ---
EXISTING_BUCKETS=$(aws s3api list-buckets --query 'Buckets[].Name' --output json)
if echo "$EXISTING_BUCKETS" | jq -e --arg b "$BUCKET" 'index($b) != null' > /dev/null; then
log INFO "Bucket $BUCKET exists — skipping."
else
aws s3api create-bucket --bucket "$BUCKET" --region "$REGION" \
--create-bucket-configuration LocationConstraint="$REGION" > /dev/null
log INFO "Bucket $BUCKET created."
fi
# Update state file
jq --arg b "$BUCKET" '.bucket = $b' "$STATE_FILE" > /tmp/_state_tmp && mv /tmp/_state_tmp "$STATE_FILE"
# --- Step 2: IAM role ---
if aws iam get-role --role-name "$ROLE" &>/dev/null; then
log INFO "Role $ROLE exists — skipping."
else
aws iam create-role --role-name "$ROLE" \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ec2.amazonaws.com"},"Action":"sts:AssumeRole"}]}' \
--output json | jq '{RoleName: .Role.RoleName, Arn: .Role.Arn}'
log INFO "Role $ROLE created."
fi
jq --arg r "$ROLE" '.role = $r' "$STATE_FILE" > /tmp/_state_tmp && mv /tmp/_state_tmp "$STATE_FILE"
log INFO "Bootstrap complete. State: $(cat "$STATE_FILE" | jq -c .)"Bilgi Kontrolü: jq ile Tekrar Çalıştırma Koruması
jq kullanarak tekrar çalıştırılabilir bulut betikleme konusundaki anlayışınızı sınayın.
Özet: CLI ve jq ile Bulut Kaynaklarını Betikleme
Bu derste kabuk betikleri, bulut CLI'ları ve jq kullanarak tekrar çalıştırılabilir bulut otomasyonunun tüm yaşam döngüsünü ele aldınız.
Temel ilkeler:
- Yazmadan önce okuyun — her zaman önce mevcut durumu sorgulayın; yalnızca fark üzerinde işlem yapın.
- Korumalar için jq -e — JSON yanıtlarından
ifdallarını yönlendirmek için çıkış durumu modunu kullanın. - Hata kodlarının anlamı — daha verimli olduğu durumlarda önceden listeleme yapmak yerine sağlayıcıya özgü hata kodlarını (örneğin
EntityAlreadyExists) yakalayın. - Eşzamansız durumu yoklayın — zaman aşımı içeren
untildöngüleri kullanın; bir kaynağın oluşturulduktan hemen sonra hazır olduğunu asla varsaymayın. - Durum dosyaları — kaynak kimliklerini ortak bir JSON dosyasına yazın; böylece betiğin her aşaması ve kaldırma işlemi aynı başvuruları paylaşır.
- Deneme çalıştırması seçenekleri — yıkıcı işlemlerden önce operatörün güvenli bir inceleme yapabilmesi için her zaman
--dry-rundesteği sağlayın.
Katı bir set -euo pipefail üst bilgisi ve bir ERR yakalama mekanizmasıyla birleştirilen bu kalıplar, C2 düzeyinde üretim ortamına uygun altyapı betiklerinin temelini oluşturur.
Sıkça Sorulan Sorular
“CLI ve jq ile Bulut Kaynaklarını Betikleme” dersi ücretsiz mi?
Evet — “CLI ve jq ile Bulut Kaynaklarını Betikleme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve DevOps Bootcamp kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. DevOps Bootcamp kursu toplamda 4 dersten oluşur.
“CLI ve jq ile Bulut Kaynaklarını Betikleme” dersinde ne öğreneceğim?
Bulut sağlayıcısı CLI'larını idempotent biçimde yönetin ve kaynakları hazırlamak ya da kaldırmak için JSON yanıtlarını ayrıştırın. DevOps Bootcamp ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
DevOps Bootcamp öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te DevOps Bootcamp, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.
“CLI ve jq ile Bulut Kaynaklarını Betikleme” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu DevOps Bootcamp dersinde kod yazıp çalıştırabilir miyim?
Evet. Her DevOps Bootcamp dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Yalın Dockerfile'lar ve Kabuk Giriş Noktaları Yazma
- envsubst ve heredoc'larla Yapılandırma Şablonlama
- CLI ve jq ile Bulut Kaynaklarını Betikleme
- Sağlık Yoklamaları, Hazırlık Kapıları ve Bekleme Döngüleri