Pilviresurssien skriptaus CLI-työkaluilla ja jq:lla
Ohjaa pilvipalveluntarjoajien CLI-työkaluja idempotentisti ja jäsennä JSON-vastauksia resurssien luomista ja poistamista varten.
Pilviresurssien skriptaus CLI-työkaluilla ja jq:lla on ilmainen DevOps-bootcamp-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu DevOps-bootcamp-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. DevOps-bootcamp-kurssilla on yhteensä 4 oppituntia.
Miksi idempotentti pilviskriptaus on tärkeää
C2-tasolla pilviskriptaus ei tarkoita painikkeiden napsauttelua — kyse on sellaisen koodin kirjoittamisesta, joka voidaan suorittaa turvallisesti useita kertoja luomatta päällekkäisiä resursseja tai epäonnistumatta toisella suorituskerralla.
Idempotentti skripti tarkistaa ennen luomista, onko resurssi jo olemassa. Tämä on luotettavan infrastruktuuriautomaation perusta.
- Pilvipalvelujen CLI-työkalut (AWS, GCP, Azure) palauttavat JSON-muotoa — tämän tulosteen jäsentäminen on olennaista.
jqon Unixin vakiotyökalu shell-skriptien JSON-tietojen poimimiseen, suodattamiseen ja muuntamiseen.- CLI:n, jq:n ja ehdollisen logiikan yhdistäminen mahdollistaa vankkojen ja toistettavien käyttöönottoskriptien kirjoittamisen.
Tämän oppitunnin aikana otatte käyttöön S3-bucketeja, EC2-instansseja ja IAM-rooleja käyttäen AWS CLI:tä esimerkkinä sekä suoraan gcloud- ja az-työkaluihin siirrettäviä malleja.
Pilvipalvelujen CLI-työkalujen asentaminen ja tarkistaminen
Varmistakaa ennen skriptausta, että oikeat työkalut ovat käytettävissä. Lukitkaa versiot aina CI-ympäristössä, jotta ympäristöjen välisiltä muutoksilta vältytään.
Alla oleva koodikatkelma tarkistaa AWS CLI v2:n, jq:n ja GCP SDK:n sekä asentaa vain puuttuvat työkalut — tämä on hyödyllinen malli uusien virtuaalikoneiden tai konttien käynnistysskripteissä.
#!/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."Olemassa olevien resurssien kysely jq:n avulla
Idempotentin skriptin ensimmäinen vaihe on luku — kysykää API:lta, onko resurssi jo olemassa, ja haarautukaa sen mukaisesti.
AWS CLI palauttaa aina JSON-muotoa. jq avulla voitte poimia juuri tarvitsemanne kentän:
jq -r '.Buckets[].Name'— raakamääräinen merkkijonotuloste, yksi bucketin nimi riviä kohden.jq -e— palauttaa poistumiskoodin 1, jos lauseke tuottaa arvonnulltaifalse, joten se sopii erinomaisestiif-ehtojen suojaksi.jq '.[] | select(.Name == env.BUCKET)'— suodattaa shell-muuttujan avulla käyttämällä komentoaenv.
Alla oleva koodikatkelma luettelee kaikki S3-bucketit ja tarkistaa, onko kohdebucket jo olemassa.
#!/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."
fiIdempotentin S3-bucketin luominen
Kun olemassaolotarkistus on paikallaan, sijoittakaa luonti suojausehdon sisään. Hyvin jäsennelty pilvifunktio noudattaa seuraavaa mallia:
- Lukekaa nykyinen tila API:lta.
- Verratkaa haluttua tilaa todelliseen tilaan.
- Toimikaa vain eron perusteella.
Huomioikaa lippu --create-bucket-configuration — sitä tarvitaan kaikilla alueilla lukuun ottamatta aluetta us-east-1. Alueen määrittäminen suoraan skriptiin estää hiljaiset epäonnistumiset, kun AWS_DEFAULT_REGION ei ole asetettu.
#!/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"Sisäkkäisen JSON-datan jäsentäminen: EC2-instanssin tila
EC2-vastaukset ovat syvästi sisäkkäisiä. jq-polkujen läpikäynti ja --query (JMESPath, AWS CLI:n oma ominaisuus) toimivat molemmat — mutta jq on tehokkaampi monimutkaisessa logiikassa.
EC2:n keskeiset jq-mallit:
.Reservations[].Instances[]— litistää kaksinkertaisen taulukkorakenteen.select(.State.Name == "running")— suodattaa tilan perusteella..Tags[] | select(.Key == "Name") | .Value— poimii tagin arvon.
Katkelma etsii Name-tagin perusteella käynnissä olevan instanssin ja palauttaa sen ID-tunnisteen sekä yksityisen IP-osoitteen.
#!/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"Idempotentin IAM-roolin käyttöönotto
IAM-resurssit ovat yleisiä, eikä niitä saa luoda kahteen kertaan. AWS palauttaa tietyn virhekoodin — EntityAlreadyExists — kun yritätte luoda jo olemassa olevan roolin. Tämän koodin käsittely on IAM-resurssien laajamittaisessa hallinnassa siistimpi idempotenssimalli kuin resurssien ennakkotarkistukseen käytettävä listauskutsu.
Alla oleva skripti havainnollistaa seuraavat asiat:
- CLI:n poistumiskoodin tallentaminen komennolla
|| true, jottaset -eei keskeytä suoritusta. - Prosessinkorvauksen avulla sen virheviestin JSON-datan jäsentäminen, jonka AWS kirjoittaa vakiovirheeseen.
- Käytännön liittäminen vain, jos sitä ei ole vielä liitetty.
#!/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:n edistyneet ominaisuudet: muunnokset, map-operaatiot ja toentries
Infrastruktuurin todelliset vastaukset sisältävät kymmeniä kenttiä. jq-muunnosten avulla voitte muotoilla tulosteen uudelleen jatkokäsittelyä, lokeja tai asetustiedostoja varten.
Keskeiset edistyneet mallit:
map(select(...))— suodattaa taulukon menettämättä taulukon ympäröivää rakennetta.to_entries | map(select(.value != null))— poistaa null-kentät ennen asetustiedostoon kirjoittamista.[.[] | {id: .InstanceId, ip: .PrivateIpAddress}]— muodostaa uuden rakenteen.@csv,@tsv,@base64— sisäänrakennetut muuntimet eri muotoihin.
Alla oleva koodikatkelma poimii kaikki käynnissä olevat instanssit ja kirjoittaa TSV-muotoisen inventaariotiedoston.
#!/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"Asynkronisten toimintojen odottaminen: tilan kysely jq:n avulla
Pilvitoiminnot ovat asynkronisia. EC2-instanssin luominen palauttaa heti tilan pending. Luotettavien skriptien on kyseltävä tilaa, kunnes haluttu tila saavutetaan ennen jatkamista.
Alla oleva malli käyttää until-silmukkaa ja eksponentiaalista viiveen pidennystä. AWS CLI tarjoaa myös wait-alakomentoja, kuten aws ec2 wait instance-running, mutta itse toteutettu tilan kysely antaa hallinnan mukautettuun aikakatkaisuun ja mahdollistaa yksityiskohtaisemman lokituksen.
#!/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."Monipilvimalli: GCP:n ja Azuren vastineet
Idempotentti lue ja toimi -malli siirtyy suoraan myös muiden pilvipalvelujen CLI-työkaluihin. Sekä gcloud että az palauttavat JSON-muotoa ja tukevat suodatusta:
- GCP:
gcloud ... --format='json'— ohjatkaa tulostejq:lle aivan kuten AWS:n kanssa. Käyttäkää komennongcloud ... --quietavulla kehotteiden piilottamista skripteissä. - Azure:
az ... --output json— sama malli toimii myös tässä.az group existspalauttaa tavallisen totuusarvomerkkijonon (true/false), joten yksinkertaisissa tapauksissa jq:tä ei tarvita.
Katkelma näyttää Azureen tehtävän resurssiryhmän idempotentin luonnin ja GCP:hen tehtävän GCS-bucketin luonnin rinnakkain samaa suojausehtomallia käyttäen.
#!/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
fiAlasajo: resurssien turvallinen tuhoaminen
Tuhoamisskriptit ovat yhtä tärkeitä kuin luontiskriptit. Turvallinen alasajo:
- Luettelee resurssit ennen minkään poistamista ja tulostaa yhteenvedon ihmisen tarkistettavaksi.
- Hyväksyy lipun
--dry-run, jotta ylläpitäjät voivat vahvistaa suunnitelman suorittamatta toimintoja. - Poistaa resurssit oikeassa riippuvuusjärjestyksessä, esimerkiksi päättää instanssit ennen suojausryhmien poistamista.
Alla oleva koodikatkelma päättää kaikki tunnisteella Env=staging merkityt EC2-instanssit --dry-run-suojauksen avulla.
#!/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."Päästä päähän: idempotentti infrastruktuurin alustusskripti
Kaikki yhteen koottuna: tuotantotason alustusskripti koordinoi useita resursseja oikeassa järjestyksessä, on täysin idempotentti ja tuottaa rakenteisia lokeja, joita CI-järjestelmä voi jäsentää.
Esitellyt keskeiset käytännöt:
- Rakenteinen lokikirjaus
log()-apuohjelman avulla. Se lisää lokimerkintöjen alkuun etuliitteet[INFO],[WARN]ja[ERROR]. - Tilatiedosto — luotujen resurssien tunnukset kirjoitetaan JSON-tilatiedostoon, jotta seuraavat ajot ja purkuskriptit käyttävät samoja viittauksia.
- Virheiden käsittely —
trapsieppaa odottamattomat poistumiset ja ilmoittaa virheen aiheuttaneen rivin numeron.
#!/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 .)"Osaamisen tarkistus: jq-idempotenssisuoja
Testatkaa ymmärrystänne idempotentista pilviskriptauksesta jq:n avulla.
Kertaus: pilviresurssien skriptaus CLI:n ja jq:n avulla
Tässä oppitunnissa käsiteltiin idempotentin pilviautomaation koko elinkaari shell-skriptien, pilvipalveluiden komentorivityökalujen ja jq:n avulla.
Keskeiset periaatteet:
- Lukekaa ennen kirjoittamista — kysykää aina olemassa oleva tila ensin ja toimikaa vain muutosten perusteella.
- jq -e suojatarkistuksiin — käyttäkää poistumiskooditilaa ohjaamaan
if-haaroja JSON-vastausten perusteella. - Virhekoodien semantiikka — käsitelkää palveluntarjoajakohtaiset virhekoodit, kuten
EntityAlreadyExists, sen sijaan että listaisitte resurssit ensin, jos se on tehokkaampaa. - Asynkronisen tilan tarkistaminen — käyttäkää aikakatkaisuilla varustettuja
until-silmukoita. Älkää koskaan olettako, että resurssi on valmis heti luomisen jälkeen. - Tilatiedostot — kirjoittakaa resurssien tunnukset jaettuun JSON-tiedostoon, jotta skriptin kaikki vaiheet ja purku käyttävät samoja viittauksia.
- Kuivaharjoitteluliput — tukekaa aina lippua
--dry-run, jotta operaattori voi tarkistaa toiminnan turvallisesti ennen tuhoavia toimia.
Nämä käytännöt — yhdessä tiukan set -euo pipefail-otsakkeen ja ERR-trapin kanssa — muodostavat tuotantotason infrastruktuurin skriptauksen perustan C2-tasolla.
Opi DevOps-bootcamp tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 142
- Oppitunnit
- 568
Usein kysytyt kysymykset
Onko oppitunti ”Pilviresurssien skriptaus CLI-työkaluilla ja jq:lla” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa DevOps-bootcamp-oppimispolun 3 oppituntia, myös oppitunnin “Pilviresurssien skriptaus CLI-työkaluilla ja jq:lla”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. DevOps-bootcamp-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Pilviresurssien skriptaus CLI-työkaluilla ja jq:lla”?
Ohjaa pilvipalveluntarjoajien CLI-työkaluja idempotentisti ja jäsennä JSON-vastauksia resurssien luomista ja poistamista varten. Harjoittelet DevOps-bootcamp-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni DevOps-bootcamp-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin DevOps-bootcamp-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.
Kuinka kauan ”Pilviresurssien skriptaus CLI-työkaluilla ja jq:lla”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä DevOps-bootcamp-oppitunnilla?
Kyllä. Jokainen DevOps-bootcamp-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Keveiden Dockerfile-tiedostojen ja shell-entripointien kirjoittaminen
- Määritysten mallintaminen envsubstilla ja heredoc-rakenteilla
- Pilviresurssien skriptaus CLI-työkaluilla ja jq:lla
- Kuntotarkistukset, valmiusportit ja odotussilmukat