- Posted on
- • Artificial Intelligence
Artificial Intelligence Multi-Cloud Automation
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Artificial Intelligence Multi-Cloud Automation with Bash: From Inventory to Action
Your cloud isn’t one cloud anymore—it’s three. Teams juggle AWS, Azure, and GCP consoles, YAMLs, and CLIs while fighting cost creep, drift, and compliance risk. What if you could orchestrate all of it from a Bash prompt and have AI generate summaries, priorities, and safe change plans on demand?
In this article, you’ll build a portable, Bash-first workflow that:
Gathers a unified multi-cloud inventory
Feeds it to an AI assistant for triage and next actions
Explains Terraform plans for safer changes
Works on Debian/Ubuntu, Fedora/RHEL, and openSUSE/SLES
You’ll get copy-pasteable commands, distro-specific install steps, and runnable scripts.
Why this matters
Multi-cloud sprawl is real: different auth flows, object names, and regions make cross-cloud tasks slow and error-prone.
Bash + cloud CLIs give you reliable access to ground truth. JSON outputs are perfect for programmatic analysis with
jq.AI provides the “glue” for decision-making: it can summarize inventories, spot drift, and suggest remediations in minutes.
This approach is incremental: start with read-only inventory and AI summaries, then progressively automate changes with guardrails.
1) Bootstrap a portable multi-cloud shell
We’ll install only what we need: CLIs, jq, and Terraform (optional but recommended).
Prerequisites (curl, jq):
- Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y curl jq
- Fedora/RHEL (dnf):
sudo dnf install -y curl jq
- openSUSE/SLES (zypper):
sudo zypper refresh
sudo zypper install -y curl jq
AWS CLI:
- Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y awscli
- Fedora/RHEL (dnf):
sudo dnf install -y awscli
- openSUSE/SLES (zypper):
sudo zypper install -y aws-cli
Azure CLI:
- Debian/Ubuntu (apt):
curl -sL https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor -o /etc/apt/keyrings/microsoft.gpg
echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/microsoft.gpg] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/azure-cli.list
sudo apt update
sudo apt install -y azure-cli
- Fedora/RHEL (dnf):
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
cat << 'EOF' | sudo tee /etc/yum.repos.d/azure-cli.repo
[azure-cli]
name=Azure CLI
baseurl=https://packages.microsoft.com/yumrepos/azure-cli
enabled=1
gpgcheck=1
gpgkey=https://packages.microsoft.com/keys/microsoft.asc
EOF
sudo dnf install -y azure-cli
- openSUSE/SLES (zypper):
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo zypper addrepo --name 'azure-cli' https://packages.microsoft.com/yumrepos/azure-cli azure-cli
sudo zypper refresh
sudo zypper install -y azure-cli
Google Cloud CLI:
- Debian/Ubuntu (apt):
sudo apt-get install -y apt-transport-https ca-certificates gnupg
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list
sudo apt update
sudo apt install -y google-cloud-cli
- Fedora/RHEL (dnf):
cat << 'EOF' | sudo tee /etc/yum.repos.d/google-cloud-sdk.repo
[google-cloud-cli]
name=Google Cloud CLI
baseurl=https://packages.cloud.google.com/yum/repos/cloud-sdk-el9-$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
sudo dnf install -y google-cloud-cli
- openSUSE/SLES (zypper):
sudo rpm --import https://packages.cloud.google.com/yum/doc/yum-key.gpg
sudo rpm --import https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
sudo zypper addrepo --name 'google-cloud-cli' https://packages.cloud.google.com/yum/repos/cloud-sdk-el9-$basearch google-cloud-cli
sudo zypper refresh
sudo zypper install -y google-cloud-cli
kubectl (optional but useful):
- Debian/Ubuntu (apt):
sudo apt update
sudo apt install -y kubectl
- Fedora/RHEL (dnf):
sudo dnf install -y kubectl
- openSUSE/SLES (zypper):
sudo zypper install -y kubernetes-client
Terraform (optional, for change automation):
- Debian/Ubuntu (apt):
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
sudo apt install -y terraform
- Fedora/RHEL (dnf):
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/$releasever/hashicorp.repo
sudo dnf install -y terraform
- openSUSE/SLES (zypper):
sudo rpm --import https://rpm.releases.hashicorp.com/gpg
sudo zypper addrepo https://rpm.releases.hashicorp.com/opensuse/hashicorp.repo
sudo zypper refresh
sudo zypper install -y terraform
Authenticate your CLIs:
# AWS
aws configure # supply key/secret or use SSO: aws sso login
# Azure
az login
az account set --subscription "<YOUR_SUBSCRIPTION_ID>"
# GCP
gcloud init
gcloud auth application-default login
Set AI credentials (for OpenAI; or point to your own compatible endpoint):
export OPENAI_API_KEY="<your_api_key>"
# Optional: override base URL if using a proxy/gateway
# export OPENAI_BASE_URL="https://api.openai.com/v1"
2) Collect a cross-cloud inventory in Bash
The script below discovers AWS EC2, Azure VMs, and GCP Compute Engine instances and emits a single JSON array. It uses only CLIs and jq.
Save as inventory.sh:
#!/usr/bin/env bash
set -euo pipefail
OPENAI_BASE_URL="${OPENAI_BASE_URL:-https://api.openai.com/v1}" # not used here, kept for later scripts
# Collect AWS instances across all regions you can see
aws_data='[]'
if command -v aws >/dev/null 2>&1; then
aws_regions=$(aws ec2 describe-regions --query 'Regions[].RegionName' --output text 2>/dev/null || true)
for r in $aws_regions; do
tmp=$(aws ec2 describe-instances --region "$r" \
--query 'Reservations[].Instances[].{cloud:"aws",region:Placement.AvailabilityZone,id:InstanceId,state:State.Name,type:InstanceType,tags:Tags}' \
--output json 2>/dev/null || echo '[]')
aws_data=$(jq -s '.[0] + .[1]' <(echo "$aws_data") <(echo "$tmp"))
done
fi
# Collect Azure VMs (requires az login + subscription selected)
az_data='[]'
if command -v az >/dev/null 2>&1; then
tmp=$(az vm list -d -o json 2>/dev/null || echo '[]')
# Normalize fields
az_data=$(echo "$tmp" | jq '[.[] | {cloud:"azure", region:.location, id:.id, state:(.powerState // "unknown"), type:.hardwareProfile.vmSize, tags:(.tags // [])}]')
fi
# Collect GCP instances (requires gcloud init)
gcp_data='[]'
if command -v gcloud >/dev/null 2>&1; then
tmp=$(gcloud compute instances list --format=json 2>/dev/null || echo '[]')
gcp_data=$(echo "$tmp" | jq '[.[] | {cloud:"gcp", region:.zone, id:.id|tostring, state:.status, type:.machineType, tags:(.tags.items // [])}]')
fi
# Merge and output
jq -s 'add' <(echo "$aws_data") <(echo "$az_data") <(echo "$gcp_data")
Run it and capture output:
bash inventory.sh | tee inventory.json
Tip: Extend this pattern to storage buckets, public IPs, security groups, and Kubernetes clusters (via kubectl get ... -o json) and merge them into the same document.
3) Let AI triage your estate and propose actions
We’ll send the JSON inventory to an AI model and ask for a concise summary with prioritized remediation steps. This is a read-only, low-risk way to get value quickly.
Save as ai_summarize_inventory.sh:
#!/usr/bin/env bash
set -euo pipefail
OPENAI_BASE_URL="${OPENAI_BASE_URL:-https://api.openai.com/v1}"
: "${OPENAI_API_KEY:?Set OPENAI_API_KEY}"
inv_file="${1:-inventory.json}"
[ -f "$inv_file" ] || { echo "Inventory file not found: $inv_file" >&2; exit 1; }
INV=$(jq -c . "$inv_file")
PAYLOAD=$(jq -n --arg inv "$INV" '
{
model: "gpt-4o-mini",
temperature: 0.2,
messages: [
{role:"system", content:"You are a senior SRE helping triage a multi-cloud environment. Be concise, structured, and action-oriented. Prefer least-privilege and safe-rollout steps."},
{role:"user", content: ("Summarize the following inventory, highlight top 5 risks (security/cost/reliability), and propose a 7-day action plan with owners and success metrics. Inventory JSON:\n\n" + $inv)}
]
}')
curl -sS -H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
"${OPENAI_BASE_URL}/chat/completions" \
| jq -r '.choices[0].message.content'
Run it:
bash ai_summarize_inventory.sh inventory.json
What you’ll typically get:
Risk list (e.g., public IPs without NSGs, unencrypted disks, old instance types)
Quick wins (stop idle dev VMs; attach encryption-by-default policies)
Owner mapping and metrics (e.g., “Reduce unattached IPs from 17 to 0; save ~$220/mo”)
Data safety note:
Redact secrets before sending to any external model.
For highly sensitive data, use an internal, self-hosted model or a gateway that enforces PII scrubbing and logging.
4) Automate changes with Terraform and AI “plan explain”
Push-button automation is powerful—but risky. A good pattern is to have AI explain a Terraform plan in plain English before you apply.
Example: explain any plan file.
Save as ai_explain.sh:
#!/usr/bin/env bash
set -euo pipefail
OPENAI_BASE_URL="${OPENAI_BASE_URL:-https://api.openai.com/v1}"
: "${OPENAI_API_KEY:?Set OPENAI_API_KEY}"
plan_file="${1:-plan.txt}"
[ -f "$plan_file" ] || { echo "Plan file not found: $plan_file" >&2; exit 1; }
PLAN=$(sed -e 's/\x1b\[[0-9;]*m//g' "$plan_file" | jq -Rs .)
PAYLOAD=$(jq -n --arg plan "$PLAN" '
{
model: "gpt-4o-mini",
temperature: 0.2,
messages: [
{role:"system", content:"You review Terraform plans for safety. Identify destructive changes, blast radius, dependency risks, and suggest safer alternatives. Output a crisp summary with a risk score (0-10) and a checklist."},
{role:"user", content: ("Explain this Terraform plan and call out any high-risk operations:\n\n" + $plan)}
]
}')
curl -sS -H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
"${OPENAI_BASE_URL}/chat/completions" \
| jq -r '.choices[0].message.content'
Usage (inside a Terraform workspace):
terraform init
terraform plan -no-color | tee plan.txt
bash ai_explain.sh plan.txt
Expected output:
Risk score with rationale (e.g., “Deleting 2 security groups may break ingress for service X”)
Safer alternatives (e.g., “Use
create_before_destroyand staged rollout”)A checklist for peer review (e.g., “Confirm backups, maintenance window, and rollback plan”)
Real-world example flow (end-to-end)
Run
inventory.shdaily via cron or CI.Trigger
ai_summarize_inventory.shand post the summary to Slack/Teams.Open a “sprint” ticket populated by the AI plan. Engineers pick up top actions.
For infra changes, have CI create a Terraform plan, attach
ai_explain.shoutput to the PR, and require human approval before apply.
This pattern has reduced “time to first action” for many teams from days to hours, and caught high-risk deletes before they reached production.
Conclusion and next steps
AI won’t manage your clouds for you—but with Bash and the right CLIs, it can drastically reduce toil, clarify priorities, and help you ship safer changes faster.
Your next steps:
1) Install the tooling above and run inventory.sh.
2) Generate your first AI triage with ai_summarize_inventory.sh.
3) Wire ai_explain.sh into your Terraform PR workflow.
4) Iterate: add more resources (buckets, security groups, Kubernetes), build policy checks, and track metrics over time.
If you want a starter repo with these scripts and a CI example, ask and I’ll share a template you can fork.