In the previous post, we learned how to call REST API with curl and jq. Now, we’ll apply those skills to cloud — where Bash combines with Cloud CLI to manage resources on AWS, GCP, Azure efficiently and automatically.
When managing cloud at scale, clicking through the web console is no longer feasible. Cloud CLI lets you start/stop instances, check status, snapshot, scale — all from the terminal. And Bash is the “glue” that connects these CLI tools into powerful automation scripts.
This post will guide you through setting up and using AWS CLI, GCP CLI, Azure CLI with Bash, querying JSON output, and building practical cloud management scripts.
Cloud CLI overview
Why use Cloud CLI?
Method
Pros
Cons
Web Console
Visual, easy to use
Slow, can’t automate
Cloud CLI
Fast, scriptable, automated
Need to learn each cloud’s syntax
Direct API
Most flexible
Complex, manual auth handling
Cloud CLI is the sweet spot — powerful enough for automation, simple enough to learn quickly. And Bash is the perfect tool to orchestrate multiple CLI tools.
#!/usr/bin/env bash
# Auto-scale GCP instance group when CPU > 80%set -euo pipefail
PROJECT="${GCP_PROJECT:-my-project}"ZONE="${GCP_ZONE:-asia-southeast1-a}"INSTANCE_GROUP="${INSTANCE_GROUP:-web-server-group}"CPU_THRESHOLD=80# Get CPU utilizationCPU_USAGE=$(gcloud monitoring time-series list \
--filter='metric.type="compute.googleapis.com/instance/cpu/utilization"'\
--interval-start-time="-PT5M"\
--format="value(points[0].value.doubleValue)" 2>/dev/null | head -1 ||echo"0")# Convert to percentageCPU_PERCENT=$(echo"$CPU_USAGE * 100"| bc 2>/dev/null | cut -d. -f1 ||echo"0")echo"Current CPU: ${CPU_PERCENT}%"if(( CPU_PERCENT > CPU_THRESHOLD ));thenecho"CPU above threshold, scaling up..." gcloud instance-groups managed set-autoscaling "$INSTANCE_GROUP"\
--zone="$ZONE"\
--project="$PROJECT"\
--min-num-replicas=2\
--max-num-replicas=10\
--target-cpu-utilization=0.7
elseecho"CPU normal, no action needed"fi
Stop all VMs after work hours (Azure)
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env bash
# Stop all VMs in resource group (for dev/test environments)set -euo pipefail
RESOURCE_GROUP="${1:?Usage: $0 <resource-group>}"echo"Stopping all VMs in resource group: $RESOURCE_GROUP"az vm stop --resource-group "$RESOURCE_GROUP" --no-wait
echo"Stop command sent. Check status with:"echo" az vm list -g $RESOURCE_GROUP --query '[].{name:name, state:powerState}' --output table"
Multi-cloud script pattern
When managing multiple clouds, an abstraction layer prevents vendor lock-in:
Security: Always store credentials in profile files (~/.aws/credentials, ~/.config/gcloud/, ~/.azure/), never hardcode in scripts. Use IAM roles/service accounts when possible.
Rate limiting: Cloud APIs have rate limits. AWS: 100-200 requests/second, GCP: varies, Azure: varies. Add sleep or retry logic for intensive API calls.
Cost awareness: Some API calls incur costs (like describe-instances on AWS). Monitor AWS Cost Explorer or equivalent to avoid surprises.
Error handling: Cloud CLI can fail for many reasons (network, permission, throttle). Always check exit codes and log details.
Parallel execution: When managing many resources, use parallel execution to speed things up, but watch out for rate limits.
Conclusion
Bash and Cloud CLI is an incredibly powerful combination in DevOps. From querying JSON output with jq, automating snapshots/scaling, to multi-cloud management — everything can be done with just Bash scripts.
With a vendor-neutral pattern like above, you can write scripts that run on any cloud provider without lock-in.
In the next post, we’ll explore Bash and Security: how to secure scripts, validate input, manage secrets, and scan with shellcheck.