0Pricing
Linux Command Line & Bash Scripting Mastery · Pelajaran

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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Linux Command Line & Bash Scripting Mastery 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.
  • jq adalah 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 menghasilkan null atau false, sehingga ideal untuk kondisi penjaga if.
  • jq '.[] | select(.Name == env.BUCKET)' — memfilter menggunakan variabel shell melalui env.

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."
fi

Pembuatan Bucket S3 Idempoten

Setelah pemeriksaan keberadaan tersedia, bungkus pembuatan dalam kondisi penjaga. Fungsi cloud yang terstruktur dengan baik mengikuti pola berikut:

  1. Baca keadaan saat ini dari API.
  2. Bandingkan keadaan yang diinginkan dengan keadaan sebenarnya.
  3. 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 || true agar set -e tidak 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 ke jq persis seperti pada AWS. Gunakan gcloud ... --quiet untuk menekan permintaan konfirmasi dalam skrip.
  • Azure: az ... --output json — polanya identik. az group exists mengembalikan 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
fi

Pembongkaran: 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-run agar 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 — trap menangkap 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 if dari 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 until dengan 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-run agar 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 Linux Command Line & Bash Scripting Mastery, upgrade ke CoddyKit PRO. Kursus Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery?

Tidak diperlukan pengalaman sebelumnya. Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery ini?

Ya. Setiap pelajaran Linux Command Line & Bash Scripting Mastery 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

  1. Menulis Dockerfile dan Entrypoint Shell yang Ringkas
  2. Membuat Template Konfigurasi dengan envsubst dan heredoc
  3. Membuat Skrip Resource Cloud dengan CLI dan jq
  4. Probe Kesehatan, Gerbang Kesiapan, dan Loop Tunggu
← Kembali ke Linux Command Line & Bash Scripting Mastery