AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

AAP 2.6 Network Automation: Cisco, Arista, Juniper, and Multi-Vendor Management

By Luca Berton · Published 2024-01-01 · Category: troubleshooting

Automate network infrastructure with AAP 2.6. Configure Cisco IOS/NX-OS, Arista EOS, Juniper Junos, and multi-vendor environments.

Network Automation with AAP 2.6

AAP 2.6 provides enterprise-grade network automation for multi-vendor environments. Unlike server automation (SSH-based), network automation uses specialized connection plugins and collections designed for network device APIs and CLIs.

See also: Ansible Network Automation: Configure Cisco, Arista, and Juniper at Scale

Connection Methods

| Connection | Protocol | Use Case | |-----------|----------|----------| | ansible.netcommon.network_cli | SSH CLI | Traditional CLI-based devices | | ansible.netcommon.netconf | NETCONF (SSH) | Juniper, Nokia, structured config | | ansible.netcommon.httpapi | REST API | Arista eAPI, Cisco NX-API | | ansible.netcommon.libssh | SSH (libssh) | High-performance SSH |

Execution Environment for Network

---
version: 3
images:
  base_image:
    name: registry.redhat.io/ansible-automation-platform-26/ee-minimal-rhel9:latest
dependencies:
  galaxy:
    collections:
      - name: ansible.netcommon
        version: ">=7.0.0"
      - name: ansible.utils
        version: ">=5.0.0"
      - name: cisco.ios
        version: ">=9.0.0"
      - name: cisco.nxos
        version: ">=9.0.0"
      - name: cisco.asa
      - name: arista.eos
        version: ">=10.0.0"
      - name: junipernetworks.junos
        version: ">=9.0.0"
      - name: vyos.vyos
      - name: community.network
  python:
    - paramiko>=3.0
    - netmiko>=4.0
    - ncclient>=0.6
    - jmespath>=1.0
    - netaddr>=1.0
    - textfsm>=1.1
    - ntc-templates>=6.0
    - xmltodict>=0.13
  system:
    - openssh-clients [platform:rpm]
    - libxml2 [platform:rpm]
    - libxslt [platform:rpm]

See also: Using the AAP 2.6 Self-Service Portal for Network Automation

Inventory for Network Devices

Static Network Inventory

- name: Create network inventory
  ansible.platform.inventory:
    controller_host: "{{ gateway_url }}"
    controller_username: "{{ controller_user }}"
    controller_password: "{{ controller_pass }}"
    name: "Network Infrastructure"
    organization: "Network Operations"
    state: present

# Cisco IOS group - name: Create Cisco IOS group ansible.platform.group: name: "cisco_ios" inventory: "Network Infrastructure" variables: ansible_network_os: cisco.ios.ios ansible_connection: ansible.netcommon.network_cli ansible_become: true ansible_become_method: enable state: present

# Arista EOS group - name: Create Arista EOS group ansible.platform.group: name: "arista_eos" inventory: "Network Infrastructure" variables: ansible_network_os: arista.eos.eos ansible_connection: ansible.netcommon.httpapi ansible_httpapi_use_ssl: true ansible_httpapi_validate_certs: false ansible_become: true ansible_become_method: enable state: present

# Juniper Junos group - name: Create Juniper Junos group ansible.platform.group: name: "juniper_junos" inventory: "Network Infrastructure" variables: ansible_network_os: junipernetworks.junos.junos ansible_connection: ansible.netcommon.netconf state: present

Network Credential

- name: Create network credential
  ansible.platform.credential:
    controller_host: "{{ gateway_url }}"
    controller_username: "{{ controller_user }}"
    controller_password: "{{ controller_pass }}"
    name: "Network SSH"
    organization: "Network Operations"
    credential_type: "Machine"
    inputs:
      username: "ansible"
      password: "{{ vault_network_password }}"
      become_password: "{{ vault_enable_password }}"
    state: present

Configuration Backup

Multi-Vendor Backup Playbook

---
- name: Backup network device configurations
  hosts: all
  gather_facts: false

tasks: - name: Backup Cisco IOS cisco.ios.ios_config: backup: true backup_options: filename: "{{ inventory_hostname }}_{{ ansible_date_time.date }}.cfg" dir_path: /var/backups/network/ when: ansible_network_os == 'cisco.ios.ios'

- name: Backup Arista EOS arista.eos.eos_config: backup: true backup_options: filename: "{{ inventory_hostname }}_{{ ansible_date_time.date }}.cfg" dir_path: /var/backups/network/ when: ansible_network_os == 'arista.eos.eos'

- name: Backup Juniper Junos junipernetworks.junos.junos_config: backup: true backup_options: filename: "{{ inventory_hostname }}_{{ ansible_date_time.date }}.cfg" dir_path: /var/backups/network/ when: ansible_network_os == 'junipernetworks.junos.junos'

- name: Push backups to Git ansible.builtin.shell: | cd /var/backups/network/ git add -A git commit -m "Network backup {{ ansible_date_time.iso8601 }}" || true git push delegate_to: localhost run_once: true

See also: Ansible NETCONF Connection Plugin: Network Configuration Protocol Complete Guide

Configuration Management

Cisco IOS Configuration

- name: Configure Cisco IOS switches
  hosts: cisco_ios
  gather_facts: false

tasks: - name: Configure hostname and domain cisco.ios.ios_hostname: config: hostname: "{{ inventory_hostname }}" domain_name: example.com

- name: Configure NTP cisco.ios.ios_ntp_global: config: servers: - server: 10.1.1.1 prefer: true - server: 10.1.1.2

- name: Configure SNMP cisco.ios.ios_snmp_server: config: communities: - name: "{{ vault_snmp_community }}" ro: true acl_v4: SNMP_ACL hosts: - host: 10.1.1.100 version: "2c" community_string: "{{ vault_snmp_community }}"

- name: Configure interfaces cisco.ios.ios_l3_interfaces: config: - name: Loopback0 ipv4: - address: "{{ loopback_ip }}/32" - name: GigabitEthernet0/1 ipv4: - address: "{{ mgmt_ip }}/24"

- name: Configure ACLs cisco.ios.ios_acls: config: - afi: ipv4 acls: - name: MGMT_ACCESS aces: - grant: permit protocol_options: tcp: ssh: true source: address: 10.0.0.0 wildcard_bits: 0.0.0.255 destination: any: true sequence: 10 - grant: deny source: any: true destination: any: true sequence: 999

Arista EOS Configuration

- name: Configure Arista EOS switches
  hosts: arista_eos
  gather_facts: false

tasks: - name: Configure BGP arista.eos.eos_bgp_global: config: as_number: "{{ bgp_asn }}" router_id: "{{ loopback_ip }}" neighbors: - neighbor_address: "{{ bgp_peer_ip }}" remote_as: "{{ bgp_peer_asn }}" description: "Uplink to Core" send_community: standard: true extended: true

- name: Configure VLANs arista.eos.eos_vlans: config: - vlan_id: 100 name: Management state: active - vlan_id: 200 name: Production state: active - vlan_id: 300 name: DMZ state: active

Juniper Junos Configuration

- name: Configure Juniper Junos
  hosts: juniper_junos
  gather_facts: false

tasks: - name: Configure system settings junipernetworks.junos.junos_config: lines: - set system host-name {{ inventory_hostname }} - set system domain-name example.com - set system name-server 10.1.1.1 - set system name-server 10.1.1.2 - set system ntp server 10.1.1.1 prefer - set system syslog host 10.1.1.100 any warning

- name: Configure firewall filter junipernetworks.junos.junos_config: src: templates/junos-firewall.j2 comment: "Ansible managed - {{ ansible_date_time.iso8601 }}" confirm: 2 # Auto-rollback after 2 minutes if not confirmed

Network Compliance Auditing

Compliance Check Playbook

---
- name: Network compliance audit
  hosts: all
  gather_facts: false

vars: compliance_results: []

tasks: - name: Gather device facts ansible.netcommon.cli_command: command: "{{ show_version_cmd }}" register: version_output vars: show_version_cmd: "{{ 'show version' if ansible_network_os != 'junipernetworks.junos.junos' else 'show version brief' }}"

- name: Check NTP is configured ansible.netcommon.cli_command: command: "{{ ntp_cmd }}" register: ntp_config vars: ntp_cmd: "{{ 'show ntp associations' if ansible_network_os == 'cisco.ios.ios' else 'show ntp status' }}"

- name: Verify SSH is enabled ansible.netcommon.cli_command: command: "show ip ssh" register: ssh_config when: ansible_network_os == 'cisco.ios.ios'

- name: Check running vs startup config cisco.ios.ios_command: commands: - show archive config differences system:running-config nvram:startup-config register: config_diff when: ansible_network_os == 'cisco.ios.ios'

- name: Flag unsaved changes ansible.builtin.debug: msg: "WARNING: {{ inventory_hostname }} has unsaved configuration changes!" when: - ansible_network_os == 'cisco.ios.ios' - config_diff.stdout[0] | length > 0

- name: Generate compliance report ansible.builtin.template: src: templates/compliance-report.j2 dest: "/var/reports/network/{{ inventory_hostname }}_compliance.html" delegate_to: localhost

Change Management Workflow

Use AAP workflow templates for network change management:

[Pre-Change Backup] → [Validate Change Request]
                            ↓ success
                    [Approval: Network Lead]
                            ↓ success
                    [Deploy to Lab]
                            ↓ success
                    [Verify Lab]
                         ↓ success      ↓ failure
                [Deploy to Production]  [Rollback Lab]
                     ↓ success   ↓ failure
                [Post-Change Verify] [Rollback Production]
                     ↓ success       ↓ always
                [Close Change Ticket] [Alert Network Team]

Rollback Playbook

- name: Rollback network configuration
  hosts: "{{ target_devices }}"
  gather_facts: false

tasks: - name: Rollback Cisco IOS cisco.ios.ios_config: replace: config src: "/var/backups/network/{{ inventory_hostname }}_{{ rollback_date }}.cfg" when: ansible_network_os == 'cisco.ios.ios'

- name: Rollback Juniper (automatic with commit confirmed) junipernetworks.junos.junos_config: rollback: 1 comment: "Rollback initiated by AAP - {{ ansible_date_time.iso8601 }}" when: ansible_network_os == 'junipernetworks.junos.junos'

- name: Verify connectivity after rollback ansible.netcommon.cli_command: command: "ping {{ mgmt_gateway }} repeat 5" register: ping_result failed_when: "'!!!!!' not in ping_result.stdout" when: ansible_network_os == 'cisco.ios.ios'

Resource Modules (Declarative Approach)

Resource modules provide idempotent, declarative network configuration:

- name: Declarative interface configuration
  cisco.ios.ios_l2_interfaces:
    config:
      - name: GigabitEthernet0/1
        mode: access
        access:
          vlan: 100
      - name: GigabitEthernet0/2
        mode: trunk
        trunk:
          allowed_vlans: "100,200,300"
          native_vlan: 1
    state: replaced  # Ensure exact match

States available for resource modules:

| State | Behavior | |-------|----------| | merged | Add/update config (default) | | replaced | Replace specific resource config | | overridden | Replace all resources of this type | | deleted | Remove specific config | | gathered | Read current config (no changes) | | parsed | Parse offline config text | | rendered | Generate device commands without applying |

FAQ

How do I handle devices that don't support collections?

Use ansible.netcommon.cli_command and ansible.netcommon.cli_config for generic CLI-based management. These work with any device that has SSH CLI access.

Can AAP manage network devices through a jump host?

Yes. Use ansible_ssh_common_args: '-o ProxyJump=jumphost.example.com' or configure hop nodes in Automation Mesh to place execution nodes in the same network as the devices.

How do I test network changes safely?

Use Juniper's commit confirmed (auto-rollback timer), Cisco's configure replace with archive, or AAP workflow templates with lab verification before production. Resource modules with state: rendered let you preview commands without applying.

Should I use CLI or API connections?

APIs (NETCONF, eAPI, NX-API) are preferred when available — they provide structured data, transactional commits, and better error handling. CLI is universal but requires parsing unstructured text output.

Can I automate network device firmware upgrades?

Yes. Use ansible.netcommon.net_put or vendor-specific modules to upload firmware, then schedule reboot with verification. Always include rollback procedures and test in lab first.

Conclusion

AAP 2.6 provides a unified platform for multi-vendor network automation. From configuration backup and compliance auditing to automated deployments with change management workflows, AAP transforms network operations from manual CLI sessions into repeatable, auditable, self-service automation.

Related Articles

AAP 2.6 Architecture and Components: Complete GuideAAP 2.6 Execution Environments: Build, Manage, and Deploy Custom EEsAAP 2.6 Workflow Templates: Advanced Multi-Step Automation GuideAAP 2.6 Automation Mesh: Distributed Execution Across Sites and NetworksAAP 2.6 Self-Service Portal for Network Teams

Category: troubleshooting

Browse all Ansible tutorials · AnsiblePilot Home