Penguasaan Baris Perintah Linux & Penskripan Bash · Pelajaran

Menskripkan Sumber Awan melalui CLI dan jq

Kawal CLI penyedia awan secara idempoten dan huraikan respons JSON untuk menyediakan serta menyahwujudkan sumber

Pelajaran 3 daripada 413 langkah

Menskripkan Sumber Awan melalui CLI dan jq ialah pelajaran Penguasaan Baris Perintah Linux & Penskripan Bash percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Penguasaan Baris Perintah Linux & Penskripan Bash, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Penguasaan Baris Perintah Linux & Penskripan Bash merangkumi sejumlah 4 pelajaran.

Mengapa Penskripan Awan Idempoten Penting

Pada tahap C2, penskripan awan bukan tentang mengklik butang — sebaliknya tentang menulis kod yang boleh dijalankan dengan selamat berulang kali tanpa mencipta sumber pendua atau gagal pada pelaksanaan kedua.

Skrip idempoten memeriksa sama ada sesuatu sumber telah wujud sebelum menciptanya. Ini ialah asas utama automasi infrastruktur yang boleh dipercayai.

  • CLI awan (AWS, GCP, Azure) mengembalikan JSON — penghuraian keluaran itu penting.
  • jq ialah alat Unix piawai untuk memilih, menapis dan mengubah JSON daripada skrip shell.
  • Menggabungkan CLI + jq + logik bersyarat membolehkan anda menulis skrip penyediaan yang kukuh dan boleh diulang.

Sepanjang pelajaran ini, anda akan menyediakan baldi S3, instans EC2 dan peranan IAM menggunakan AWS CLI sebagai rujukan, dengan corak yang boleh dipindahkan terus kepada gcloud dan az.

Memasang dan Mengesahkan CLI Awan

Sebelum menulis skrip, pastikan alat yang betul tersedia. Sentiasa mengunci versi dalam CI untuk mengelakkan perbezaan antara persekitaran.

Petikan kod di bawah memeriksa kewujudan AWS CLI v2, jq dan SDK GCP, lalu memasang hanya komponen yang tiada — corak yang berguna dalam skrip penyediaan awal untuk mesin maya atau bekas baharu.

#!/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 Pertanyaan tentang Sumber Sedia Ada dengan jq

Langkah pertama bagi mana-mana skrip idempoten ialah bacaan — tanyakan API sama ada sumber itu sudah wujud, kemudian buat cabang sewajarnya.

AWS CLI sentiasa mengembalikan JSON. jq membolehkan anda mengekstrak tepat medan yang diperlukan:

  • jq -r '.Buckets[].Name' — keluaran rentetan mentah, satu nama baldi setiap baris.
  • jq -e — keluar dengan kod 1 jika ungkapan menghasilkan null atau false, menjadikannya ideal sebagai pengawal if.
  • jq '.[] | select(.Name == env.BUCKET)' — tapis menggunakan pemboleh ubah shell melalui env.

Petikan kod di bawah menyenaraikan semua baldi S3 dan memeriksa sama ada baldi sasaran sudah wujud.

#!/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

Penciptaan Baldi S3 Idempoten

Dengan semakan kewujudan tersedia, bungkus penciptaan dalam pengawal. Fungsi awan yang distrukturkan dengan baik mengikuti corak ini:

  1. Baca keadaan semasa daripada API.
  2. Bandingkan keadaan dikehendaki dengan keadaan sebenar.
  3. Bertindak hanya berdasarkan perbezaan.

Perhatikan bendera --create-bucket-configuration — bendera ini diperlukan untuk semua rantau kecuali us-east-1. Menetapkan rantau secara keras dalam skrip mengelakkan kegagalan senyap apabila 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"

Menghuraikan JSON Bersarang: Keadaan Instans EC2

Respons EC2 sangat bersarang. Penelusuran laluan jq dan --query (JMESPath, tersedia secara natif dalam AWS CLI) kedua-duanya berfungsi — tetapi jq lebih berkuasa untuk logik kompleks.

Corak utama jq untuk EC2:

  • .Reservations[].Instances[] — ratakan struktur tatasusunan berganda.
  • select(.State.Name == "running") — tapis mengikut keadaan.
  • .Tags[] | select(.Key == "Name") | .Value — ekstrak nilai tag.

Petikan kod mencari instans yang sedang berjalan berdasarkan tag Name dan mengembalikan ID serta IP peribadinya.

#!/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 Peranan IAM Idempoten

Sumber IAM bersifat global dan tidak boleh diduplikasi. AWS mengembalikan kod ralat khusus — EntityAlreadyExists — apabila anda cuba mencipta peranan yang sudah wujud. Menangkap kod tersebut ialah corak idempoten yang lebih kemas daripada panggilan penyenaraian prasemakan apabila mengendalikan IAM pada skala besar.

Skrip di bawah menunjukkan:

  • Menangkap kod keluar CLI dengan || true supaya set -e tidak menghentikan pelaksanaan.
  • Menghuraikan JSON mesej ralat yang ditulis AWS ke stderr menggunakan penggantian proses.
  • Melampirkan dasar hanya jika dasar itu belum dilampirkan.
#!/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 Lanjutan: Transformasi, Pemetaan dan toentries

Respons infrastruktur sebenar mengandungi berpuluh-puluh medan. Transformasi jq membolehkan anda membentuk semula keluaran untuk alat hiliran, catatan atau fail konfigurasi.

Corak lanjutan penting:

  • map(select(...)) — tapis tatasusunan tanpa kehilangan pembungkus tatasusunan.
  • to_entries | map(select(.value != null)) — alih keluar medan null sebelum menulisnya ke dalam konfigurasi.
  • [.[] | {id: .InstanceId, ip: .PrivateIpAddress}] — unjurkan kepada bentuk baharu.
  • @csv, @tsv, @base64 — penukar format terbina dalam.

Petikan kod di bawah mengekstrak semua instans yang sedang berjalan dan menulis fail inventori 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 Tak Segerak: Tinjauan Berkala dengan jq

Operasi awan bersifat tak segerak. Penciptaan instans EC2 mengembalikan kawalan serta-merta dengan keadaan pending. Skrip yang boleh dipercayai mesti membuat tinjauan berkala sehingga keadaan yang dikehendaki dicapai sebelum meneruskan.

Corak di bawah menggunakan gelung until dengan jeda yang meningkat secara eksponen. AWS CLI turut menyediakan subperintah wait (contohnya aws ec2 wait instance-running), tetapi tinjauan berkala yang dibina sendiri memberi kawalan tamat masa tersuai dan pengelogan yang lebih terperinci.

#!/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."

Corak Berbilang Awan: Padanan GCP dan Azure

Corak baca-kemudian-tindak idempoten boleh dipindahkan terus kepada CLI awan yang lain. Kedua-dua gcloud dan az mengembalikan JSON serta menyokong penapisan:

  • GCP: gcloud ... --format='json' — salurkan kepada jq tepat seperti dengan AWS. Gunakan gcloud ... --quiet untuk menyenyapkan gesaan dalam skrip.
  • Azure: az ... --output json — coraknya sama. az group exists mengembalikan rentetan biasa yang mengandungi nilai benar/palsu (true/false), jadi jq tidak diperlukan untuk kes mudah.

Petikan kod menunjukkan penciptaan idempoten kumpulan sumber dalam Azure dan penciptaan baldi GCS dalam GCP sebelah-menyebelah dengan menggunakan corak pengawal 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

Pembersihan: Pemusnahan Sumber yang Selamat

Skrip pemusnahan sama pentingnya dengan skrip penciptaan. Proses pembersihan yang selamat:

  • Menyenaraikan sumber sebelum memadam apa-apa dan mencetak ringkasan untuk semakan manusia.
  • Menerima bendera --dry-run supaya pengendali boleh mengesahkan rancangan tanpa melaksanakan tindakan.
  • Memadam mengikut susunan kebergantungan yang betul (contohnya, menamatkan instans sebelum memadam kumpulan keselamatan).

Petikan kod di bawah menamatkan semua instans EC2 yang ditag Env=staging dengan pengawal pelaksanaan percubaan.

#!/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."

Skrip Pemulaan Infrastruktur Idempoten Hujung ke Hujung

Keseluruhannya: skrip pemulaan bertaraf pengeluaran mengatur berbilang sumber mengikut urutan yang betul, sepenuhnya idempoten dan menghasilkan log berstruktur yang boleh dihuraikan oleh sistem integrasi berterusan.

Amalan utama yang ditunjukkan:

  • Pengelogan berstruktur melalui pembantu log() yang menambah awalan [INFO], [WARN], [ERROR].
  • Fail keadaan — tulis ID sumber yang dicipta ke dalam fail keadaan JSON supaya pelaksanaan seterusnya dan skrip peleraian berkongsi rujukan yang sama.
  • Perangkap ralat — trap menangkap keluar yang tidak dijangka dan melaporkan nombor 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 .)"

Semakan Pengetahuan: Pengawal Idempotensi jq

Uji pemahaman anda tentang penskripan awan idempoten dengan jq.

Imbas Kembali: Penskripan Sumber Awan melalui CLI dan jq

Pelajaran ini merangkumi keseluruhan kitar hayat automasi awan idempoten menggunakan skrip cangkerang, CLI awan dan jq.

Prinsip teras:

  • Baca sebelum tulis — sentiasa semak keadaan sedia ada dahulu; hanya lakukan tindakan berdasarkan perbezaannya.
  • jq -e untuk pengawal — gunakan mod status keluar untuk menentukan cabang if berdasarkan respons JSON.
  • Semantik kod ralat — tangkap kod ralat khusus penyedia seperti EntityAlreadyExists dan bukannya menyenaraikan sumber terlebih dahulu apabila cara itu lebih cekap.
  • Tinjau keadaan tak segerak — gunakan gelung until dengan masa tamat; jangan sekali-kali menganggap sumber sedia serta-merta selepas dicipta.
  • Fail keadaan — tulis ID sumber ke dalam fail JSON dikongsi supaya setiap fasa skrip dan proses peleraian berkongsi rujukan yang sama.
  • Bendera percubaan — sentiasa sokong --dry-run untuk semakan operator yang selamat sebelum tindakan merosakkan dilakukan.

Corak ini — digabungkan dengan pengepala ketat set -euo pipefail dan perangkap ERR — membentuk asas penskripan infrastruktur bertaraf pengeluaran pada tahap C2.

Percuma untuk bermula

Pelajari Bash dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
22
Pelajaran
88

Soalan Lazim

Adakah pelajaran “Menskripkan Sumber Awan melalui CLI dan jq” percuma?

Ya — teks penuh “Menskripkan Sumber Awan melalui CLI dan jq” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Penguasaan Baris Perintah Linux & Penskripan Bash, tingkat taraf kepada CoddyKit PRO. Kursus Penguasaan Baris Perintah Linux & Penskripan Bash merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Menskripkan Sumber Awan melalui CLI dan jq”?

Kawal CLI penyedia awan secara idempoten dan huraikan respons JSON untuk menyediakan serta menyahwujudkan sumber Anda berlatih Penguasaan Baris Perintah Linux & Penskripan Bash menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Penguasaan Baris Perintah Linux & Penskripan Bash?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Penguasaan Baris Perintah Linux & Penskripan Bash di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “Menskripkan Sumber Awan melalui CLI dan jq” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Penguasaan Baris Perintah Linux & Penskripan Bash ini?

Ya. Setiap pelajaran Penguasaan Baris Perintah Linux & Penskripan Bash menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Menulis Dockerfile dan Titik Masuk Shell yang Ringkas
  2. Menyediakan Templat Konfigurasi dengan envsubst dan heredoc
  3. Menskripkan Sumber Awan melalui CLI dan jq
  4. Probe Kesihatan, Gerbang Kesediaan dan Gelung Menunggu
← Kembali ke Penguasaan Baris Perintah Linux & Penskripan Bash