Posted on
Artificial Intelligence

Artificial Intelligence Network Automation with Ansible

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

Artificial Intelligence Network Automation with Ansible: From Intent to Configuration

What if your change window didn’t start with a blank CLI and sweaty palms—but with a clear, auditable plan that turns business intent into safe, validated network changes? Pairing AI with Ansible makes that possible. You keep the human judgment; AI accelerates the boring parts (structuring data, boilerplate config, and documentation), and Ansible applies and validates changes consistently.

In this post, you’ll learn a practical workflow to turn plain-English network intent into configuration via Ansible, with guardrails like check mode, diffs, and post-change validation. You’ll get copy-pasteable commands, vendor-neutral patterns, and real examples.

Why AI + Ansible is worth your time

  • Consistency and speed: Ansible’s idempotence and templates remove manual repetition. AI helps you go from “what the network should do” to “structured variables” faster.

  • Fewer errors: You can standardize configuration via templates and validate outcomes programmatically. AI can help synthesize intent, but the automation enforces correctness.

  • Human-in-the-loop: Treat AI like a junior engineer—great at drafting, not at deciding. You review the diff, validate results, and approve the change.

  • Scales across vendors: Ansible’s collections support Cisco IOS, Arista EOS, Juniper Junos, and more. Your workflow stays the same even if your hardware doesn’t.


Prerequisites and installation

Pick one: install Ansible via your distribution’s package manager, then add optional Python packages in a virtual environment.

  • Ubuntu/Debian (apt):
sudo apt update
sudo apt install -y ansible python3-venv python3-pip git sshpass
  • Fedora (dnf):
sudo dnf install -y ansible python3 python3-pip git sshpass
  • RHEL/CentOS Stream (dnf):
sudo dnf install -y epel-release
sudo dnf install -y ansible python3 python3-pip git sshpass
  • openSUSE Leap/Tumbleweed (zypper):
sudo zypper refresh
sudo zypper install -y ansible python3 python3-pip git sshpass

Create and activate a Python virtual environment for optional network libraries:

python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install netmiko napalm ansible-lint jmespath

Install the Ansible network collections you need:

ansible-galaxy collection install \
  ansible.netcommon cisco.ios arista.eos junipernetworks.junos

Security tip: Don’t hardcode credentials. Use Ansible Vault, environment variables, or your secrets manager.


The workflow at a glance

1) Model network intent as data (inventory + group_vars).
2) Use AI to convert free-form requirements into structured YAML variables.
3) Render and push config via Ansible templates and network modules.
4) Validate and enforce with check mode, diffs, and post-change assertions.
5) Close the loop with compliance checks and Git-based review.

Below is a minimal end-to-end example you can adapt.


1) Model your network as data

Set up your inventory and group variables. Example for Cisco IOS branch routers:

# inventory/hosts.ini
[branch_routers]
r1 ansible_host=10.0.0.11
r2 ansible_host=10.0.0.12

[all:vars]
ansible_network_os=cisco.ios.ios
ansible_connection=ansible.netcommon.network_cli
ansible_user=netops
# Store this in Vault or set via extra-vars. Example:
# ansible_password='{{ vault_netops_password }}'
ansible_become=yes
ansible_become_method=enable

A sample group_vars file (what we’ll teach AI to produce):

# group_vars/branch_routers.yml
ntp_servers:
  - 192.0.2.10
  - 192.0.2.11
snmp:
  ro_community: BRANCHMON
  ro_acl: 10
banner_login: |
  Authorized access only. Monitoring in effect.
ospf:
  process_id: 10
  uplink_interfaces:
    - GigabitEthernet0/0
    - GigabitEthernet0/1
  area: 0

2) Let AI help translate intent into structured YAML

You can ask an LLM to turn free-form intent into precisely structured variables. Keep a human in the loop: review the YAML before using it.

Install a minimal client:

pip install openai PyYAML

Set your API key:

export OPENAI_API_KEY="your_api_key_here"

Create intent.txt describing your baseline:

Branches must use NTP servers 192.0.2.10 and 192.0.2.11.
Set SNMP read-only community BRANCHMON limited by ACL 10.
Set the login banner to "Authorized access only. Monitoring in effect."
Uplink interfaces Gi0/0 and Gi0/1 should be in OSPF area 0 with process ID 10.

Use this helper script to produce strict YAML variables:

#!/usr/bin/env python3
# intent2vars.py
import os, sys, yaml
from openai import OpenAI

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

intent = sys.stdin.read()
prompt = f"""
You are a network automation assistant. Convert the following intent into strict YAML with keys:
ntp_servers (list of IPs), snmp: {{ro_community, ro_acl}}, banner_login (string),
ospf: {{process_id (int), area (int), uplink_interfaces (list of strings)}}.
Only output YAML. Do not include explanations.
Intent:
{intent}
"""

resp = client.chat.completions.create(
    model="gpt-4o-mini",  # or another chat-capable model available to you
    messages=[{"role": "user", "content": prompt}],
    temperature=0
)

yaml_text = resp.choices[0].message.content.strip()
data = yaml.safe_load(yaml_text)

os.makedirs("group_vars", exist_ok=True)
with open("group_vars/branch_routers.yml", "w") as f:
    yaml.safe_dump(data, f, sort_keys=False)

print("Wrote group_vars/branch_routers.yml")

Run it:

chmod +x intent2vars.py
cat intent.txt | ./intent2vars.py
git diff group_vars/branch_routers.yml  # review before applying!

Note: Use your preferred AI provider or local model. Always review and test outputs.


3) Render configurations with Jinja2 and push via Ansible

Create a Jinja2 template:

# templates/branch_base.j2
service timestamps debug datetime msec
service timestamps log datetime msec
no ip domain-lookup
banner login ^
{{ banner_login | default('') }}
^

{% if ntp_servers | default([]) %}
{% for s in ntp_servers %}
ntp server {{ s }}
{% endfor %}
{% endif %}

snmp-server community {{ snmp.ro_community }} ro {{ snmp.ro_acl }}

router ospf {{ ospf.process_id }}
{% for intf in ospf.uplink_interfaces %}
 interface {{ intf }}
  ip ospf {{ ospf.process_id }} area {{ ospf.area }}
{% endfor %}

Create a playbook to render and push:

# playbooks/apply_branch_base.yml

- name: Apply branch base config
  hosts: branch_routers
  gather_facts: no
  collections:
    - cisco.ios
  tasks:
    - name: Render candidate config
      ansible.builtin.template:
        src: templates/branch_base.j2
        dest: "{{ inventory_hostname }}-candidate.cfg"
      delegate_to: localhost

    - name: Push config to device (safe to try with --check)
      ios_config:
        src: "{{ inventory_hostname }}-candidate.cfg"
        save_when: modified
      diff: yes

Dry-run first:

ansible-playbook -i inventory/hosts.ini playbooks/apply_branch_base.yml --check --diff

If the diff looks correct, apply for real:

ansible-playbook -i inventory/hosts.ini playbooks/apply_branch_base.yml --diff

Tip: Store device credentials in Ansible Vault and pass --ask-vault-pass or use a secure CI secret.


4) Validate outcomes automatically

Don’t stop at “applied.” Verify the state you intended exists.

# playbooks/validate.yml

- name: Validate branch routers
  hosts: branch_routers
  gather_facts: no
  collections:
    - cisco.ios
  tasks:
    - name: Show NTP associations
      ios_command:
        commands:
          - show ntp associations
      register: ntp_out

    - name: Confirm SNMP community exists
      ios_command:
        commands:
          - show running-config | include snmp-server community
      register: snmp_out

    - name: Prepare facts for assertions
      ansible.builtin.set_fact:
        ntp_text: "{{ ntp_out.stdout[0] | default('') }}"
        snmp_text: "{{ snmp_out.stdout[0] | default('') }}"

    - name: Assert checks passed
      ansible.builtin.assert:
        that:
          - ntp_text is search('192\\.0\\.2\\.10|192\\.0\\.2\\.11')
          - "'BRANCHMON' in snmp_text"
        fail_msg: "Post-change validation failed. Check NTP/SNMP."

Run the validation:

ansible-playbook -i inventory/hosts.ini playbooks/validate.yml

For deeper, vendor-agnostic checks, consider NAPALM validation or show-command parsing using TextFSM/ntc-templates.


5) Close the loop: compliance and GitOps

  • Keep inventory, templates, and vars in Git. Review YAML and diffs via pull requests.

  • Run ansible-playbook --check --diff nightly to detect drift without changing devices.

  • Make validation a CI job; fail the pipeline if assertions don’t pass.

  • Iteratively expand your “intent-to-vars” pattern to QoS, ACL standards, or interface baselines.


Real-world scenario recap

  • Intent: Standardize NTP, SNMP, banners, and OSPF uplinks on branch routers.

  • AI’s role: Convert English requirements into a structured group_vars/branch_routers.yml.

  • Ansible’s role: Render a vendor-specific config from a template, show diffs, apply safely, and validate outcomes.

  • Guardrails: Human review of YAML and diffs; post-change assertions; Vault for secrets; Git history for traceability.


Common pitfalls and tips

  • Connectivity: Ensure SSH reachability and correct ansible_network_os/ansible_connection values.

  • Secrets: Never commit plaintext passwords. Use Ansible Vault or your organization’s secret store.

  • AI parsing: Constrain outputs to strict schemas and inspect them. AI drafts; you approve.

  • Start small: Baselines first (NTP, SNMP, banners). Expand to routing and policy once you trust the loop.


Call to Action

  • Initialize a lab repo and try the workflow end-to-end today:
mkdir -p netops/{inventory,group_vars,playbooks,templates}
cd netops
# Add the files shown above
git init && git add . && git commit -m "AI-assisted Ansible network baseline"
  • Pick one small intent, generate group_vars with the helper script, run --check --diff, and validate.

  • When you’re comfortable, wire this into your team’s Git/CI flow and expand coverage.

If you want a lightweight starter pack, tell me your target platform(s) and I’ll generate a ready-to-clone skeleton with inventory, templates, and validation tasks tailored to your lab.