Back to Learn
Ansible network automation lab
A multi-vendor playbook lab (Cisco IOS & Juniper JunOS) that teaches core Ansible network patterns one runnable playbook at a time.
Ansible
Cisco IOS
Juniper JunOS
Network Automation
Variables, loops & dynamic device lists
Conditionals & multi-vendor branching
Handlers, roles, Vault & Jinja2 templating
Playbooks by concept
config_backup.yml
Variables + loops
Iterates a list of devices and writes a config backup file per host into a backup directory.
config_backup.yml
yaml
---
- name: Network Config Backup Automation
hosts: localhost
gather_facts: false
vars:
backup_dir: "./backup"
devices:
- { hostname: jarvis-rtr-blr-01, ip: 10.0.0.1, type: cisco_ios, site: Bangalore }
- { hostname: jarvis-fw-blr-01, ip: 10.0.0.3, type: juniper_srx, site: Bangalore }
tasks:
- name: Create backup directory
ansible.builtin.file:
path: "{{ backup_dir }}"
state: directory
- name: Back up config for each device
ansible.builtin.copy:
content: |
hostname {{ item.hostname }}
interface GigabitEthernet0/0
ip address {{ item.ip }} 255.255.255.0
no shutdown
end
dest: "{{ backup_dir }}/{{ item.hostname }}_backup.txt"
loop: "{{ devices }}"bgp_health_check.yml
Conditionals (when)
Reports each BGP neighbour state and raises a warning for any neighbour not in Established.
bgp_health_check.yml
yaml
---
- name: BGP Neighbor Health Check
hosts: localhost
gather_facts: false
vars:
bgp_neighbors:
- { ip: 10.10.10.1, state: Established }
- { ip: 10.10.10.3, state: Idle }
tasks:
- name: Show BGP status
ansible.builtin.debug:
msg: "Neighbor {{ item.ip }} is {{ item.state }}"
loop: "{{ bgp_neighbors }}"
- name: Alert for failed neighbors
ansible.builtin.debug:
msg: "WARNING: Neighbor {{ item.ip }} is DOWN"
when: item.state != "Established"
loop: "{{ bgp_neighbors }}"conditionals.yml
Multi-vendor logic
Branches on device type and environment so the same playbook applies Cisco vs Juniper logic safely.
conditionals.yml
yaml
---
- name: Conditionals Practice
hosts: localhost
gather_facts: false
vars:
device_type: "cisco"
env_type: "production"
tasks:
- name: Cisco specific config
ansible.builtin.debug:
msg: "Applying Cisco IOS commands"
when: device_type == "cisco"
- name: Juniper specific config
ansible.builtin.debug:
msg: "Applying Juniper JunOS commands"
when: device_type == "juniper"
- name: Production safety check
ansible.builtin.debug:
msg: "WARNING - Production change, double check"
when: env_type == "production"handlers.yml
Event-driven (notify)
Tasks notify handlers only when they report a change, so services restart just once at the end.
handlers.yml
yaml
---
- name: Handlers Practice
hosts: localhost
gather_facts: false
tasks:
- name: Update NTP config
ansible.builtin.debug:
msg: "NTP config updated"
changed_when: true
notify: Restart NTP service
handlers:
- name: Restart NTP service
ansible.builtin.debug:
msg: "HANDLER - NTP service restarted"Inventory
inventory.ini
ini
[local]
localhost ansible_connection=local
[routers]
# Add real devices here
[all:vars]
ansible_python_interpreter=/usr/bin/python3Run it
terminal
bash
# Install the vendor collections
ansible-galaxy collection install cisco.ios junipernetworks.junos
# Run any lab playbook
ansible-playbook -i inventory.ini config_backup.yml
ansible-playbook -i inventory.ini bgp_health_check.yml
ansible-playbook -i inventory.ini conditionals.yml