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_destroy and 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.sh daily via cron or CI.

  • Trigger ai_summarize_inventory.sh and 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.sh output 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.