Membuat Skrip Resource Cloud dengan CLI dan jq
Kendalikan CLI penyedia cloud secara idempoten dan uraikan respons JSON untuk menyediakan serta menghapus resource.
Membuat Skrip Resource Cloud dengan CLI dan jq adalah pelajaran DevOps Bootcamp gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar DevOps Bootcamp, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus DevOps Bootcamp mencakup 4 pelajaran total.
Mengapa Penulisan Skrip Cloud Idempoten Itu Penting
Pada tingkat C2, penulisan skrip cloud bukan tentang mengklik tombol — melainkan menulis kode yang dapat dijalankan dengan aman berkali-kali tanpa membuat sumber daya duplikat atau gagal pada eksekusi kedua.
Skrip idempoten memeriksa apakah suatu sumber daya sudah ada sebelum membuatnya. Inilah dasar otomasi infrastruktur yang andal.
- CLI cloud (AWS, GCP, Azure) mengembalikan JSON — mengurai keluaran tersebut sangat penting.
jqadalah alat Unix standar untuk memotong, memfilter, dan mengubah JSON dari skrip shell.- Menggabungkan CLI, jq, dan logika kondisional memungkinkan Anda menulis skrip penyediaan yang tangguh dan dapat diulang.
Sepanjang pelajaran ini, Anda akan menyediakan bucket S3, instans EC2, dan peran IAM menggunakan AWS CLI sebagai acuan, dengan pola yang dapat langsung diterapkan pada gcloud dan az.
Memasang dan Memverifikasi CLI Cloud
Sebelum menulis skrip, pastikan alat yang tepat telah tersedia. Selalu tetapkan versi secara pasti dalam CI untuk menghindari perbedaan antarlingkungan.
Potongan kode di bawah ini memeriksa AWS CLI v2, jq, dan SDK GCP, lalu hanya memasang yang belum tersedia — pola yang berguna dalam skrip bootstrap untuk mesin virtual atau kontainer baru.
#!/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."Membuat Kueri Sumber Daya yang Sudah Ada dengan jq
Langkah pertama dalam skrip idempoten apa pun adalah pembacaan — tanyakan kepada API apakah sumber daya tersebut sudah ada, lalu tentukan cabang yang sesuai.
AWS CLI selalu mengembalikan JSON. jq memungkinkan Anda mengekstrak tepat bidang yang diperlukan:
jq -r '.Buckets[].Name'— keluaran string mentah, satu nama bucket per baris.jq -e— keluar dengan kode 1 jika ekspresi menghasilkannullataufalse, sehingga ideal untuk kondisi penjagaif.jq '.[] | select(.Name == env.BUCKET)'— memfilter menggunakan variabel shell melaluienv.
Potongan kode di bawah ini mencantumkan semua bucket S3 dan memeriksa apakah bucket target sudah ada.
#!/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."
fiPembuatan Bucket S3 Idempoten
Setelah pemeriksaan keberadaan tersedia, bungkus pembuatan dalam kondisi penjaga. Fungsi cloud yang terstruktur dengan baik mengikuti pola berikut:
- Baca keadaan saat ini dari API.
- Bandingkan keadaan yang diinginkan dengan keadaan sebenarnya.
- Lakukan tindakan hanya pada perbedaannya.
Perhatikan opsi --create-bucket-configuration — opsi ini diperlukan untuk semua wilayah kecuali us-east-1. Menetapkan wilayah secara langsung di dalam skrip mencegah kegagalan diam-diam saat AWS_DEFAULT_REGION tidak ditetapkan.
#!/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"Mengurai JSON Bertingkat: Keadaan Instans EC2
Respons EC2 memiliki struktur yang sangat bertingkat. Penelusuran jalur dengan jq dan --query (JMESPath, bawaan AWS CLI) sama-sama dapat digunakan — tetapi jq lebih kuat untuk logika yang kompleks.
Pola utama jq untuk EC2:
.Reservations[].Instances[]— meratakan struktur array ganda.select(.State.Name == "running")— memfilter berdasarkan keadaan..Tags[] | select(.Key == "Name") | .Value— mengekstrak nilai tag.
Potongan kode ini menemukan instans yang sedang berjalan berdasarkan tag Name, lalu mengembalikan ID dan IP privatnya.
#!/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"Penyediaan Peran IAM Idempoten
Sumber daya IAM bersifat global dan tidak boleh dibuat duplikat. AWS mengembalikan kode galat khusus — EntityAlreadyExists — saat Anda mencoba membuat peran yang sudah ada. Menangkap kode tersebut merupakan pola idempotensi yang lebih rapi daripada melakukan panggilan daftar pemeriksaan awal saat menangani IAM dalam skala besar.
Skrip di bawah ini menunjukkan:
- Mengambil kode keluar CLI dengan
|| trueagarset -etidak menghentikan eksekusi. - Mengurai JSON pesan galat yang ditulis AWS ke aliran galat standar menggunakan substitusi proses.
- Melampirkan kebijakan hanya jika kebijakan tersebut belum terlampir.
#!/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 Tingkat Lanjut: Transformasi, Pemetaan, dan toentries
Respons infrastruktur nyata berisi puluhan bidang. Transformasi jq memungkinkan Anda membentuk ulang keluaran untuk alat lanjutan, log, atau berkas konfigurasi.
Pola tingkat lanjut yang penting:
map(select(...))— memfilter array tanpa menghilangkan pembungkus array.to_entries | map(select(.value != null))— menghapus bidang null sebelum menulis ke konfigurasi.[.[] | {id: .InstanceId, ip: .PrivateIpAddress}]— memproyeksikan data ke bentuk baru.@csv,@tsv,@base64— pengonversi format bawaan.
Potongan kode di bawah ini mengekstrak semua instans yang sedang berjalan dan menulis berkas inventaris TSV.
#!/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"Menunggu Operasi Asinkron: Pemantauan Berkala dengan jq
Operasi cloud berlangsung secara asinkron. Pembuatan instans EC2 segera mengembalikan hasil dengan keadaan pending. Skrip yang andal harus memeriksa berulang kali hingga keadaan yang diinginkan tercapai sebelum melanjutkan.
Pola di bawah ini menggunakan perulangan until dengan jeda mundur eksponensial. AWS CLI juga menyediakan subperintah wait (misalnya aws ec2 wait instance-running), tetapi pemantauan manual memberi Anda kendali batas waktu khusus dan pencatatan log yang lebih rinci.
#!/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."Pola Multi-Cloud: Padanan GCP dan Azure
Pola idempoten baca-lalu-tindak dapat diterapkan langsung pada CLI cloud lainnya. gcloud dan az sama-sama mengembalikan JSON dan mendukung pemfilteran:
- GCP:
gcloud ... --format='json'— salurkan kejqpersis seperti pada AWS. Gunakangcloud ... --quietuntuk menekan permintaan konfirmasi dalam skrip. - Azure:
az ... --output json— polanya identik.az group existsmengembalikan string boolean sederhana (true/false), sehingga jq tidak diperlukan untuk kasus sederhana.
Potongan kode ini menunjukkan pembuatan grup sumber daya yang idempoten di Azure dan pembuatan bucket GCS di GCP secara berdampingan menggunakan pola penjaga yang sama.
#!/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
fiPembongkaran: Penghancuran Sumber Daya yang Aman
Skrip penghancuran sama pentingnya dengan skrip pembuatan. Pembongkaran yang aman:
- Mencantumkan sumber daya sebelum menghapus apa pun dan mencetak ringkasan untuk ditinjau manusia.
- Menerima opsi
--dry-runagar operator dapat mengonfirmasi rencana tanpa menjalankannya. - Menghapus dalam urutan dependensi yang benar (misalnya, mengakhiri instans sebelum menghapus grup keamanan).
Potongan kode di bawah ini mengakhiri semua instans EC2 yang diberi tag Env=staging dengan kondisi dry run.
#!/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."Dari Ujung ke Ujung: Skrip Inisialisasi Infrastruktur Idempoten
Menyatukan semuanya: skrip inisialisasi berstandar produksi mengatur berbagai sumber daya dalam urutan yang benar, sepenuhnya idempoten, dan menghasilkan log terstruktur yang dapat diuraikan oleh sistem integrasi berkelanjutan.
Praktik utama yang diperagakan:
- Pencatatan log terstruktur melalui pembantu
log()yang menambahkan awalan[INFO],[WARN],[ERROR]. - Berkas status — tuliskan ID sumber daya yang dibuat ke berkas status JSON agar eksekusi berikutnya dan skrip penghentian dapat menggunakan referensi yang sama.
- Perangkap kesalahan —
trapmenangkap penghentian yang tidak terduga dan melaporkan nomor baris yang gagal.
#!/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 .)"Pemeriksaan Pengetahuan: Pengaman Idempotensi dengan jq
Uji pemahaman Anda tentang pembuatan skrip komputasi awan idempoten dengan jq.
Ringkasan: Membuat Skrip Sumber Daya Komputasi Awan melalui CLI dan jq
Pelajaran ini membahas seluruh siklus hidup otomatisasi komputasi awan idempoten menggunakan skrip shell, CLI komputasi awan, dan jq.
Prinsip utama:
- Baca sebelum menulis — selalu periksa status yang ada terlebih dahulu; lakukan tindakan hanya berdasarkan perbedaannya.
- jq -e untuk pengaman — gunakan mode status keluar untuk mengendalikan cabang
ifdari respons JSON. - Semantik kode kesalahan — tangkap kode kesalahan khusus penyedia, misalnya
EntityAlreadyExists, alih-alih mencantumkan semua sumber daya terlebih dahulu jika cara tersebut lebih efisien. - Periksa status asinkron secara berkala — gunakan perulangan
untildengan batas waktu; jangan pernah berasumsi bahwa sumber daya langsung siap setelah dibuat. - Berkas status — tuliskan ID sumber daya ke berkas JSON bersama agar setiap tahap skrip dan proses penghentian menggunakan referensi yang sama.
- Opsi simulasi — selalu dukung
--dry-runagar operator dapat melakukan peninjauan yang aman sebelum tindakan yang merusak.
Pola-pola ini — dipadukan dengan header set -euo pipefail yang ketat dan perangkap ERR — membentuk dasar pembuatan skrip infrastruktur berstandar produksi pada tingkat C2.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Membuat Skrip Resource Cloud dengan CLI dan jq” gratis?
Ya — teks lengkap “Membuat Skrip Resource Cloud dengan CLI dan jq” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus DevOps Bootcamp, upgrade ke CoddyKit PRO. Kursus DevOps Bootcamp mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Membuat Skrip Resource Cloud dengan CLI dan jq”?
Kendalikan CLI penyedia cloud secara idempoten dan uraikan respons JSON untuk menyediakan serta menghapus resource. Kamu berlatih DevOps Bootcamp dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai DevOps Bootcamp?
Tidak diperlukan pengalaman sebelumnya. DevOps Bootcamp di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Membuat Skrip Resource Cloud dengan CLI dan jq” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran DevOps Bootcamp ini?
Ya. Setiap pelajaran DevOps Bootcamp menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Menulis Dockerfile dan Entrypoint Shell yang Ringkas
- Membuat Template Konfigurasi dengan envsubst dan heredoc
- Membuat Skrip Resource Cloud dengan CLI dan jq
- Probe Kesehatan, Gerbang Kesiapan, dan Loop Tunggu