- Posted on
- • Artificial Intelligence
Artificial Intelligence in DevOps: Bash Automation Best Practices
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
Artificial Intelligence in DevOps: Bash Automation Best Practices
When a 3 a.m. pager goes off, you don’t want to “think,” you want to act. AI can help you automate triage, summarize failures, label risky changes, and generate just‑enough documentation—if your Bash foundation is solid. This guide shows how to combine reliable Bash practices with lightweight AI integrations you can run from any CI/CD pipeline or terminal.
What you’ll get:
A hardened Bash skeleton you can reuse in every repo
Quality gates with ShellCheck
A portable AI CLI via curl + jq
Real-world examples for risk labeling and log triage
Install instructions for apt, dnf, and zypper
Why AI + Bash is worth your time
Speed: AI accelerates toil-heavy tasks—summarizing logs, drafting postmortems, and reviewing diffs for risk.
Consistency: Prompted “standard operating procedures” yield repeatable outcomes during incidents.
Reach: Bash is everywhere. A small, portable AI wrapper lets you add intelligence without replatforming your pipelines.
Control: Keep your production automation predictable while safely offloading analysis to AI.
Install prerequisites
The examples use only standard CLI tools and a cloud AI API (OpenAI-compatible). Install the basics:
- Ubuntu/Debian (apt)
sudo apt update
sudo apt install -y curl jq git shellcheck parallel golang-go
- Fedora/RHEL/CentOS Stream (dnf)
sudo dnf install -y curl jq git ShellCheck parallel golang
- openSUSE (zypper)
sudo zypper refresh
sudo zypper install -y curl jq git ShellCheck parallel go
Optional: shfmt (formatting). If your distro doesn’t package it, install via Go:
# Install shfmt (requires Go)
GO111MODULE=on go install mvdan.cc/sh/v3/cmd/shfmt@latest
# Add Go bin to PATH (usually in ~/.bashrc or ~/.profile)
export PATH="$PATH:$(go env GOPATH)/bin"
Note: The first time you run GNU parallel, it may prompt you to acknowledge a citation.
1) Harden your Bash: reliability first
Use a robust script skeleton. This avoids subtle failures and makes AI-augmented steps safe to call.
#!/usr/bin/env bash
# skeleton.sh - Safe Bash skeleton you can source or copy
set -Eeuo pipefail
IFS=$'\n\t'
umask 027
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG() { printf '%s %-5s %s\n' "$(date -Is)" "${1:-INFO}" "${*:2}" >&2; }
cleanup() {
# example: rm -f "${TMP_FILES[@]:-}"
:
}
on_error() {
local ec=$?
LOG ERROR "Failed at ${BASH_SOURCE[1]}:${BASH_LINENO[0]}: ${BASH_COMMAND} (exit $ec)"
}
trap cleanup EXIT
trap on_error ERR
require() { command -v "$1" >/dev/null || { LOG ERROR "Missing dependency: $1"; exit 127; }; }
TMP_FILES=()
mktempf() { local f; f="$(mktemp)"; TMP_FILES+=("$f"); echo "$f"; }
retry() {
# retry <times> <cmd...> ; exponential backoff
local tries="$1"; shift
local n=0
until "$@"; do
(( n++ >= tries )) && return 1
sleep $((2**n))
done
}
# Example usage:
# require curl jq
# f="$(mktempf)"
# retry 3 curl -fsS --max-time 15 -o "$f" "https://example.com/ping"
# LOG INFO "Downloaded to $f"
Key practices:
set -Eeuo pipefail and a strict IFS to catch errors early
trap ERR and EXIT for debugging and cleanup
Small utilities: require, retry, mktempf, and a timestamped logger
Keep scripts idempotent where possible
2) Lint and gate your scripts with ShellCheck (and optional shfmt)
Prevent footguns before they ship to CI/CD or production.
- Run locally:
# Lint every shell script in the repo
find . -type f -name '*.sh' -not -path '*/.git/*' -print0 \
| xargs -0 -n1 shellcheck -x
- Optional formatting with shfmt (installed via Go above):
shfmt -w -i 2 -ci -sr .
- CI “quality gate” example (run in your pipeline):
#!/usr/bin/env bash
set -Eeuo pipefail
find . -type f -name '*.sh' -print0 | xargs -0 -n1 shellcheck -x
Treat ShellCheck warnings as blockers for reliability—AI integrations are only as good as the scripts they’re glued to.
3) Add a portable AI CLI you can call from Bash
This AI wrapper uses any OpenAI-compatible endpoint (OpenAI, Azure OpenAI with a compatible gateway, or a self-hosted compatible service). Keep secrets in environment variables.
Create ai.sh:
#!/usr/bin/env bash
# ai.sh - tiny AI CLI that reads prompt from STDIN and returns text
set -Eeuo pipefail
: "${OPENAI_API_KEY:?Set OPENAI_API_KEY}"
OPENAI_BASE_URL="${OPENAI_BASE_URL:-https://api.openai.com}"
OPENAI_MODEL="${OPENAI_MODEL:-gpt-4o-mini}"
AI_SYSTEM_PROMPT="${AI_SYSTEM_PROMPT:-You are a concise, senior DevOps assistant. Respond briefly and use JSON when asked.}"
prompt="$(cat -)"
json_payload="$(jq -n \
--arg model "$OPENAI_MODEL" \
--arg sys "$AI_SYSTEM_PROMPT" \
--arg usr "$prompt" \
'{model:$model, temperature:0,
messages:[ {role:"system",content:$sys}, {role:"user",content:$usr} ] }'
)"
curl -fsS --max-time 30 -H "Authorization: Bearer ${OPENAI_API_KEY}" \
-H 'Content-Type: application/json' \
-X POST "${OPENAI_BASE_URL}/v1/chat/completions" \
-d "$json_payload" \
| jq -r '.choices[0].message.content'
Usage:
export OPENAI_API_KEY="sk-..."
# Optional:
# export OPENAI_BASE_URL="https://api.openai.com"
# export OPENAI_MODEL="gpt-4o-mini"
echo 'Summarize: kube-scheduler restart caused pending pods' | ./ai.sh
Tips:
Make outputs machine-parseable by instructing JSON format in the prompt.
Add timeouts and retries (see skeleton) for resilience.
Redact secrets before sending data to AI (see next section).
4) Real-world examples you can drop into CI/CD today
A) Risk-label a pull request diff before merge
Gate merges by asking AI to classify risk. If “high,” fail the job and require a human review.
risk-label.sh:
#!/usr/bin/env bash
set -Eeuo pipefail
require() { command -v "$1" >/dev/null || { echo "Missing $1" >&2; exit 127; }; }
require git jq ./ai.sh
BASE_REF="${BASE_REF:-origin/main}" # set in CI as needed
DIFF="$(git fetch --quiet "${BASE_REF%/*}" || true; git diff --unified=0 "${BASE_REF}"...HEAD || true)"
read -r -d '' PROMPT <<'EOF'
You are a release risk classifier. Read this unified diff and output strict JSON:
{"risk":"low|medium|high","reasons":["...","..."],"areas":["infra","app","security","data","other"]}
Heuristics:
- high: changes to deployment manifests, secrets, auth, network, DB schema, or many files
- medium: changes to scripts/runbooks affecting pipelines or observability
- low: comments, docs, tests only
Return only JSON. No additional text.
EOF
payload="$(printf '%s\n\nDiff:\n%s\n' "$PROMPT" "$DIFF" | ./ai.sh)"
echo "AI classification:"
echo "$payload" | jq
risk="$(echo "$payload" | jq -r '.risk // "low"')"
if [[ "$risk" == "high" ]]; then
echo "Merge blocked: high risk detected."
exit 42
fi
CI step example:
#!/usr/bin/env bash
set -Eeuo pipefail
export OPENAI_API_KEY="$AI_TOKEN_FROM_VAULT"
./risk-label.sh
Outcome: routine changes flow quickly, high-risk edits get an extra set of eyes.
B) AI-assisted log triage after a failed job
Summarize large logs, highlight root causes and actionable next steps. Redact sensitive data before sending to AI.
log-triage.sh:
#!/usr/bin/env bash
set -Eeuo pipefail
require() { command -v "$1" >/dev/null || { echo "Missing $1" >&2; exit 127; }; }
require jq sed awk split ./ai.sh
LOG_FILE="${1:-/var/log/ci/last-failure.log}"
WORK_DIR="$(mktemp -d)"
trap 'rm -rf "$WORK_DIR"' EXIT
# Redact common secrets/tokens
redact() {
sed -E \
-e 's/(Authorization: Bearer )[A-Za-z0-9\._-]+/\1REDACTED/gI' \
-e 's/([Pp]assword|[Tt]oken|[Ss]ecret|API[_-]?KEY)[^[:alnum:]]+[[:graph:]]+/REDACTED/g' \
-e 's/[A-Za-z0-9+\/]{35,}={0,2}/REDACTED_BASE64/g'
}
# Sample recent, diverse lines
tail -n 5000 "$LOG_FILE" \
| awk '!seen[$0]++' \
| redact \
> "$WORK_DIR/clean.log"
# Chunk to ~100KB per part to keep requests small and cheap
split -C 100k -d "$WORK_DIR/clean.log" "$WORK_DIR/chunk_"
cat > "$WORK_DIR/system.txt" <<'SYS'
You are an SRE triage assistant. Summarize the chunk:
- probable root cause(s)
- key errors/warnings with timestamps
- impacted components
- suggested next actions (numbered)
Return concise Markdown.
SYS
summaries=()
for f in "$WORK_DIR"/chunk_*; do
out="$f.summary.md"
( cat "$WORK_DIR/system.txt"; echo; echo '--- LOG CHUNK START ---'; cat "$f"; echo '--- LOG CHUNK END ---' ) \
| AI_SYSTEM_PROMPT="$(cat "$WORK_DIR/system.txt")" ./ai.sh > "$out"
summaries+=("$out")
done
# Final cross-chunk synthesis
{
echo "Triage Summary (AI)"
echo
printf 'Processed %d chunk(s).\n\n' "${#summaries[@]}"
for s in "${summaries[@]}"; do
echo "----"
cat "$s"
echo
done
echo "----"
echo "Consolidated view:"
printf 'Please merge duplicates, rank root causes, and output a final action list.\n' \
| ./ai.sh
} > triage.md
echo "Wrote triage.md"
Result: a concise triage.md capturing likely root cause, signals, and next steps—fast enough for incident response.
C) Generate up-to-date script docs from comments
Keep script usage docs fresh with a quick AI pass.
docgen.sh:
#!/usr/bin/env bash
set -Eeuo pipefail
require() { command -v "$1" >/dev/null || { echo "Missing $1" >&2; exit 127; }; }
require ./ai.sh
FILE="${1:?Usage: docgen.sh path/to/script.sh}"
read -r -d '' P <<'EOF'
Read the Bash script below. Produce:
- brief description
- required env vars
- flags and defaults
- example invocations
Format as Markdown. Be accurate to the code.
EOF
{ echo "$P"; echo; cat "$FILE"; } | ./ai.sh > "${FILE}.md"
echo "Wrote ${FILE}.md"
Drop this into CI to regenerate mini-READMEs automatically when scripts change.
Practical guardrails for AI in pipelines
Scope and redaction: Remove secrets/tokens and PII from prompts. See redact() above.
Cost control: Keep prompts small, summarize in stages, and set low temperature with concise instructions.
Determinism: Ask for strict JSON and validate with jq before acting on results.
Timeouts and retries: Use curl timeouts and your retry() utility.
Observability: Log AI request sizes, response codes, and decisions (e.g., risk labels) for audits.
Conclusion and next steps
AI can be a reliable teammate for DevOps—if your Bash is battle-hardened and your prompts are disciplined. To get started today: 1) Install the prerequisites with your package manager (apt/dnf/zypper). 2) Add the skeleton.sh patterns to your scripts. 3) Drop ai.sh into your repo and export OPENAI_API_KEY. 4) Pilot one workflow: risk-label diffs or log triage. 5) Measure outcomes (MTTR, review throughput, false positives) and iterate.
When you’re ready, expand to documentation generation, playbook drafting, and incident summarization. Small, safe steps compound quickly.