Posted on
Artificial Intelligence

Artificial Intelligence Network Automation Projects

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

AI + Bash: 3 Network Automation Projects You Can Ship This Week

If you’ve ever spent a midnight maintenance window grepping logs, diffing configs, and sketching topologies on a whiteboard, this one’s for you. AI doesn’t replace your network intuition—it amplifies it. With a handful of shell scripts and an LLM endpoint, you can unlock faster triage, safer changes, and cleaner documentation… all from your Linux terminal.

This article shows you three practical, Bash-first AI network automation projects you can build today:

  • AI-tagged network inventory and quick topology map

  • AI-powered syslog summarizer for noisy outages

  • Pre/post change validation with AI risk summaries

Each project includes copy/paste scripts and clear install instructions for apt, dnf, and zypper.


Why this matters now

  • Network ops time isn’t spent on keystrokes—it’s spent on interpretation. LLMs are good at summarizing, pattern matching, and classifying text. Your devices output text. That’s a match.

  • You already have the data. SNMP, LLDP, syslog, and simple reachability tests produce enough signal for AI to add value—no new telemetry needed.

  • Bash glue beats platform sprawl. You can keep your trusted Linux toolkit and add AI in small, safe increments.


Prerequisites and installation

The scripts below are POSIX-friendly and depend on common CLI tools. Install the following packages.

Debian/Ubuntu (apt):

sudo apt update
sudo apt install -y curl jq nmap snmp lldpd graphviz traceroute
sudo systemctl enable --now lldpd

Fedora/RHEL/CentOS (dnf):

sudo dnf install -y curl jq nmap net-snmp-utils lldpd graphviz traceroute
sudo systemctl enable --now lldpd

openSUSE (zypper):

sudo zypper refresh
sudo zypper install -y curl jq nmap net-snmp lldpd graphviz traceroute
sudo systemctl enable --now lldpd

You also need access to an LLM with an OpenAI-compatible HTTP API. Many hosted and local options expose /v1/chat/completions. Configure these environment variables once:

export AI_BASE_URL="http://localhost:8000/v1"   # or your provider's base URL
export AI_MODEL="my-network-model"              # model name at your endpoint
export AI_API_KEY="sk-..."                      # if your endpoint requires it

Note:

  • Only scan and query networks you’re authorized to test.

  • SNMP community shown here is for lab use. Use SNMPv3 in production.


Project 1: AI‑tagged inventory and a quick topology sketch

Goal: Produce a JSON inventory labeled with AI-inferred device roles (core/distribution/access/firewall/router/etc.), then draw a tiny topology from LLDP data.

What it does:

  • Pings the subnet with nmap -sn to find live hosts.

  • Pulls SNMP sysName/sysDescr; optionally LLDP neighbors.

  • Asks the LLM to classify each device role from its description.

  • Emits inventory.json and a topology.png via Graphviz.

ai-inventory.sh:

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

CIDR="${1:-192.168.1.0/24}"
COMMUNITY="${COMMUNITY:-public}"
OUT_JSON="${OUT_JSON:-inventory.json}"
DOT_FILE="${DOT_FILE:-topology.dot}"

# Require: curl jq nmap snmp graphviz
: "${AI_BASE_URL:?Set AI_BASE_URL}"; : "${AI_MODEL:?Set AI_MODEL}"
AI_AUTH_HEADER=()
[[ -n "${AI_API_KEY:-}" ]] && AI_AUTH_HEADER=(-H "Authorization: Bearer $AI_API_KEY")

echo "[] " > "$OUT_JSON"

echo "[*] Scanning $CIDR for live hosts..."
mapfile -t HOSTS < <(nmap -sn "$CIDR" -oG - | awk '/Up$/{print $2}')

role_color() {
  case "$1" in
    core) echo "#e41a1c" ;;
    distribution) echo "#377eb8" ;;
    access) echo "#4daf4a" ;;
    firewall) echo "#ff7f00" ;;
    router) echo "#984ea3" ;;
    wireless) echo "#a65628" ;;
    load-balancer) echo "#f781bf" ;;
    *) echo "#999999" ;;
  esac
}

declare -A EDGES
echo "graph G {" > "$DOT_FILE"
echo '  graph [overlap=false, splines=true, bgcolor="#ffffff"]; node [shape=box, style=filled, fontname="Arial"];' >> "$DOT_FILE"

for ip in "${HOSTS[@]}"; do
  echo "[*] Querying SNMP on $ip"
  name="$(snmpget -v2c -c "$COMMUNITY" -Oqv "$ip" SNMPv2-MIB::sysName.0 2>/dev/null || true)"
  descr="$(snmpget -v2c -c "$COMMUNITY" -Oqv "$ip" SNMPv2-MIB::sysDescr.0 2>/dev/null || true)"

  # AI classification prompt
  prompt="Given this network device fingerprint:
IP: $ip
sysName: ${name:-N/A}
sysDescr: ${descr:-N/A}

Classify JSON only with keys: role (one of: core, distribution, access, firewall, router, wireless, load-balancer, unknown) and vendor (guess)."
  ai_json="$(curl -sS "$AI_BASE_URL/chat/completions" \
      -H "Content-Type: application/json" "${AI_AUTH_HEADER[@]}" \
      -d "$(jq -n --arg m "$AI_MODEL" --arg p "$prompt" \
          '{model:$m, temperature:0.1, messages:[{role:"user", content:$p}]}')" \
      | jq -r '.choices[0].message.content' 2>/dev/null || echo '{"role":"unknown","vendor":"unknown"}')"

  role="$(jq -r '.role // "unknown"' <<<"$ai_json" 2>/dev/null || echo unknown)"
  vendor="$(jq -r '.vendor // "unknown"' <<<"$ai_json" 2>/dev/null || echo unknown)"
  color="$(role_color "$role")"

  # Append to inventory JSON
  tmp="$(mktemp)"
  jq --arg ip "$ip" --arg name "$name" --arg descr "$descr" --arg role "$role" --arg vendor "$vendor" \
     '. += [{"ip":$ip,"sysName":$name,"sysDescr":$descr,"role":$role,"vendor":$vendor}]' "$OUT_JSON" > "$tmp" && mv "$tmp" "$OUT_JSON"

  # Node
  label="$(printf "%s\n%s\n(%s)" "${name:-$ip}" "$role" "$vendor")"
  safe_node="$(sed 's/[^A-Za-z0-9_]/_/g' <<<"$ip")"
  echo "  \"$safe_node\" [label=\"$(echo "$label" | sed 's/"/\\"/g')\", fillcolor=\"$color\"];" >> "$DOT_FILE"

  # LLDP neighbors (best-effort)
  # lldpRemSysName: 1.0.8802.1.1.2.1.4.1.1.9
  while read -r neigh; do
    [[ -z "$neigh" ]] && continue
    neigh_node="$(sed 's/[^A-Za-z0-9_]/_/g' <<<"$neigh")"
    key="${safe_node}--${neigh_node}"
    EDGES["$key"]=1
  done < <(snmpwalk -v2c -c "$COMMUNITY" -Oqv -On "$ip" 1.0.8802.1.1.2.1.4.1.1.9 2>/dev/null | sed 's/"//g' | sort -u)
done

# Edges (undirected)
for e in "${!EDGES[@]}"; do
  a="${e%%--*}"; b="${e##*--}"
  [[ "$a" == "$b" ]] && continue
  echo "  \"$a\" -- \"$b\";" >> "$DOT_FILE"
done

echo "}" >> "$DOT_FILE"

echo "[*] Wrote $OUT_JSON and $DOT_FILE"
echo "[*] Rendering topology.png ..."
dot -Tpng "$DOT_FILE" -o topology.png
echo "[+] Done. Open topology.png"

Run it:

COMMUNITY=public ./ai-inventory.sh 192.168.1.0/24

What you get:

  • inventory.json: a quick inventory with AI-inferred roles and vendors.

  • topology.png: a clean map derived from LLDP where available.

Tip: If your devices don’t expose LLDP via SNMP, run lldpd locally and parse lldpcli show neighbors as an alternative enrichment step.


Project 2: AI syslog triage in 60-second windows

Goal: Turn a firehose of logs into actionable bullets during incidents.

What it does:

  • Every minute, grabs the last ~500 lines of logs.

  • Groups repeated messages, highlights deltas, and asks the LLM to produce a concise incident summary with likely root causes and next actions.

ai-syslog-summarizer.sh:

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

: "${AI_BASE_URL:?Set AI_BASE_URL}"; : "${AI_MODEL:?Set AI_MODEL}"
AI_AUTH_HEADER=()
[[ -n "${AI_API_KEY:-}" ]] && AI_AUTH_HEADER=(-H "Authorization: Bearer $AI_API_KEY")

# Detect a reasonable journal source across distros; fallback to /var/log/messages or /var/log/syslog
journal_cmd="journalctl --since '-1 minute' -o short-iso"
if ! command -v journalctl >/dev/null 2>&1; then
  if [[ -f /var/log/messages ]]; then
    journal_cmd="tail -n 500 /var/log/messages"
  else
    journal_cmd="tail -n 500 /var/log/syslog"
  fi
fi

while :; do
  ts="$(date -Is)"
  echo "[*] $ts summarizing last minute of logs..."
  logs="$($journal_cmd | tail -n 500)"

  # Compact similar lines by stripping timestamps/PIDs to create brief signatures
  sigs="$(sed -E 's/[A-Za-z]{3} [ 0-9]{2} [0-9:]{8}(\.[0-9]+)? //; s/[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:]+\.[0-9]+[+-][0-9:]+ //; s/\[[0-9]+\]/[]/g' <<<"$logs" \
        | awk '{count[$0]++} END {for (k in count) printf("%6d  %s\n", count[k], k)}' \
        | sort -nr | head -n 40 )"

  prompt="You are a network SRE assistant. Summarize these log patterns from the last minute.
Output:

- Top 5 issues with counts

- Likely root causes (network-centric if applicable)

- Concrete next actions (1-3 items)

- Risk level: low/medium/high

Log patterns (count + message):
$sigs"

  summary="$(curl -sS "$AI_BASE_URL/chat/completions" \
      -H "Content-Type: application/json" "${AI_AUTH_HEADER[@]}" \
      -d "$(jq -n --arg m "$AI_MODEL" --arg p "$prompt" \
          '{model:$m, temperature:0.2, messages:[{role:"user", content:$p}]}')" \
      | jq -r '.choices[0].message.content' || echo "(no summary)")"

  printf "\n==== %s Incident Summary ====\n%s\n\n" "$ts" "$summary"

  sleep 60
done

Run it:

./ai-syslog-summarizer.sh

Tip:

  • Pipe the summary to your chat tool or ticket system.

  • Tune --since and head -n to match your log volume.


Project 3: “Change Guard” — AI‑assisted pre/post checks for blast radius

Goal: When changes go live, quickly confirm reachability and path stability to critical endpoints, and get an AI risk summary.

What it does:

  • Runs targeted TCP port checks with nmap and short traceroutes before and after a change.

  • Diffs the results and asks the LLM to label material changes, possible causes, and user impact.

Prepare a file of targets (one host or host:port per line):

# targets.txt
10.10.10.10:443
10.10.20.20:22
app.example.com:443
db.example.com:5432

change-guard.sh:

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

MODE="${1:-}"   # pre or post
TARGETS_FILE="${2:-targets.txt}"
[[ "$MODE" == "pre" || "$MODE" == "post" ]] || { echo "Usage: $0 pre|post [targets.txt]"; exit 1; }

OUT_DIR=".change-guard"
mkdir -p "$OUT_DIR"

: "${AI_BASE_URL:?Set AI_BASE_URL}"; : "${AI_MODEL:?Set AI_MODEL}"
AI_AUTH_HEADER=()
[[ -n "${AI_API_KEY:-}" ]] && AI_AUTH_HEADER=(-H "Authorization: Bearer $AI_API_KEY")

# Split host:port; accumulate unique hosts and ports
mapfile -t LINES < <(grep -vE '^\s*#' "$TARGETS_FILE" | awk 'NF')
ports=()
hosts=()
for l in "${LINES[@]}"; do
  if [[ "$l" == *:* ]]; then
    h="${l%%:*}"; p="${l##*:}"
    hosts+=("$h"); ports+=("$p")
  else
    hosts+=("$l")
  fi
done
# Unique ports; default to 22,80,443 if none given
if [[ "${#ports[@]}" -eq 0 ]]; then ports=(22 80 443); fi
unique_ports="$(printf "%s\n" "${ports[@]}" | sort -u | paste -sd, -)"
printf "%s\n" "${hosts[@]}" | sort -u > "$OUT_DIR/hosts.list"

echo "[*] $MODE: TCP reachability scan on $(wc -l < "$OUT_DIR/hosts.list") hosts, ports: $unique_ports"
nmap -Pn -T4 --open -iL "$OUT_DIR/hosts.list" -p "$unique_ports" -oG "$OUT_DIR/${MODE}.gnmap" >/dev/null

echo "[*] $MODE: quick traceroutes (first 5 hops)"
{
  while read -r h; do
    echo "### $h"
    traceroute -n -w 1 -q 1 -m 5 "$h" 2>/dev/null | sed 's/^/    /'
  done < "$OUT_DIR/hosts.list"
} > "$OUT_DIR/${MODE}.tr.txt"

if [[ "$MODE" == "post" ]]; then
  echo "[*] Diffing results..."
  reach_diff="$(diff -u "$OUT_DIR/pre.gnmap" "$OUT_DIR/post.gnmap" || true)"
  trace_diff="$(diff -u "$OUT_DIR/pre.tr.txt" "$OUT_DIR/post.tr.txt" || true)"
  prompt="You are a network change-validation assistant.
Given pre/post TCP reachability and traceroute diffs, assess:

- Material changes (ports newly closed/opened, path length changes, new AS hops)

- Probable causes (ACL, route, NAT/firewall, DNS, MTU, etc.)

- User impact and blast radius

- Clear recommendation (proceed/rollback/investigate) and 2-3 next actions

Reachability diff:
$reach_diff

Traceroute diff:
$trace_diff"

  summary="$(curl -sS "$AI_BASE_URL/chat/completions" \
      -H "Content-Type: application/json" "${AI_AUTH_HEADER[@]}" \
      -d "$(jq -n --arg m "$AI_MODEL" --arg p "$prompt" \
          '{model:$m, temperature:0.1, messages:[{role:"user", content:$p}]}')" \
      | jq -r '.choices[0].message.content' || echo "(no summary)")"

  printf "\n==== Change Guard Summary ====\n%s\n" "$summary"
  echo "[+] Artifacts in $OUT_DIR/: pre/post.gnmap, pre/post.tr.txt"
else
  echo "[+] Pre-change artifacts written to $OUT_DIR/. Run again with: $0 post [targets.txt]"
fi

Run it:

# Before the change window:
./change-guard.sh pre targets.txt

# After the change:
./change-guard.sh post targets.txt

Result:

  • Nmap and traceroute artifacts for audit.

  • A compact, explainable AI report with risks and next steps.


Operational tips and guardrails

  • Least privilege: Use read-only SNMP and avoid credentials in shell history. Prefer SNMPv3 where supported.

  • Scope scans: Provide explicit CIDRs or hostlists. Rate-limit nmap as needed.

  • Log hygiene: Mask PII or secrets before sending to any external AI endpoint.

  • Cost/latency: Batch prompts and set low temperature for deterministic outputs.

  • Reproducibility: Commit your scripts and inventory JSON to version control.


Conclusion and next steps

You don’t need a new platform to get AI value in NetOps. With Bash, a few standard tools, and an LLM endpoint, you can:

  • Generate a living, labeled inventory and quick topology sketches.

  • Triage noisy incidents into clear action plans.

  • Validate change windows with defensible, auditable checks.

Try these scripts in a lab this week. Then:

  • Add SNMPv3 and vendor-specific enrichments.

  • Pipe summaries to your team chat or ticketing system.

  • Wrap each script with systemd timers for scheduled runs.

If you want a deeper dive, reply with your environment details (vendors, telemetry sources), and I’ll help tailor these scripts to your network.