
In today’s fast-paced IT landscape, network engineering managers are under growing pressure to implement faster, more reliable, and secure network operations. Automation is no longer a luxury—it’s a necessity. Among the most powerful tools for network automation is Ansible, and when paired with Juniper network devices, it offers a robust solution to manage infrastructure at scale while reducing human error, increasing deployment speed, and enabling consistent configuration across the network estate.
As networks grow in complexity and scale, manual configuration becomes increasingly impractical. Network automation with Ansible for Juniper devices provides a pathway to operational excellence through programmable infrastructure, allowing teams to shift from repetitive manual tasks to strategic initiatives that drive business value.
Ansible is an open-source automation engine that simplifies the orchestration, configuration, and management of IT infrastructure. Unlike many other automation tools, Ansible uses a declarative approach where you specify the desired state of your systems rather than the steps to achieve that state.
Key features of Ansible that make it particularly valuable for Juniper network automation include:
This combination of features makes Ansible an ideal choice for organizations looking to automate their Juniper network infrastructure while maintaining control and visibility.
Juniper Networks is a popular enterprise-grade vendor known for its high-performance networking equipment running the Junos operating system. Juniper’s commitment to programmability and automation makes their devices particularly well-suited for Ansible-based automation.
The Ansible Junos modules, available through Juniper’s official juniper.junos Ansible collection, provide comprehensive capabilities for managing Junos devices:
juniper_junos_config: Load and commit configuration changesjuniper_junos_facts: Gather system information and operational datajuniper_junos_command: Run operational CLI commands and parse the outputjuniper_junos_software: Upgrade device software imagesjuniper_junos_ping: Test network connectivityjuniper_junos_rpc: Execute specific RPCs on devicesjuniper_junos_table: Retrieve and parse operational data using PyEZ TablesAll these modules require NETCONF to be enabled on the Junos devices, which is Juniper’s implementation of the standard network configuration protocol. NETCONF provides a programmatic interface for managing configurations using XML encoding, which Ansible leverages for device communication.
Before diving into playbooks, you need to set up a proper Ansible environment for Juniper automation:
First, install Python, Ansible, and the necessary libraries:
# Install Python and pip if not already available
sudo apt update
sudo apt install python3 python3-pip
# Install Ansible
pip3 install ansible
# Install PyEZ (Juniper's Python library) and required dependencies
pip3 install junos-eznc jxmlease
# Install the Juniper.junos collection for Ansible
ansible-galaxy collection install juniper.junosCreate an ansible.cfg file in your project directory with network-specific settings:
[defaults]
inventory = ./inventory
host_key_checking = False
timeout = 30
retry_files_enabled = False
gathering = explicit
stdout_callback = yaml
[persistent_connection]
connect_timeout = 60 command_timeout = 60Define your Juniper devices in an inventory file:
# inventory.ini
[juniper_routers]
router1 ansible_host=192.168.1.1
router2 ansible_host=192.168.1.2
[juniper_switches]
sw1 ansible_host=192.168.1.10
sw2 ansible_host=192.168.1.11
sw3 ansible_host=192.168.1.12
[juniper:children]
juniper_routers
juniper_switches
[juniper:vars]
ansible_network_os=junos
ansible_connection=netconf
ansible_user=netadmin
ansible_password=secure_password
ansible_python_interpreter=/usr/bin/python3Note: For production environments, never store passwords in plain text. Use Ansible Vault or environment variables instead.
Now let’s explore practical examples of automating Juniper devices with Ansible:
Create a playbook to gather facts from your Juniper devices:
---
# gather_facts.yml
- name: Collect Juniper Device Information
hosts: juniper
gather_facts: no
collections:
- juniper.junos
tasks:
- name: Gather Junos facts
juniper_junos_facts:
savedir: "./facts"
register: junos_facts
- name: Display device information
debug:
msg: "{{ inventory_hostname }} is running Junos {{ junos_facts.ansible_facts.junos.version }} on a {{ junos_facts.ansible_facts.junos.model }}"Run this playbook:
ansible-playbook gather_facts.ymlCreate a playbook to configure VLANs:
---
# configure_vlans.yml
- name: Configure VLANs on Juniper Switches
hosts: juniper_switches
gather_facts: no
collections:
- juniper.junos
tasks:
- name: Load VLAN configuration
juniper_junos_config:
load: merge
format: set
lines:
- set vlans engineering vlan-id 100
- set vlans engineering description "Engineering Department"
- set vlans finance vlan-id 200
- set vlans finance description "Finance Department"
- set vlans management vlan-id 999
- set vlans management description "Network Management"
comment: "Configuring standard VLANs"
confirm: 2
register: config_result
- name: Show configuration results
debug:
var: config_resultRun the VLAN configuration playbook:
ansible-playbook configure_vlans.ymlFor more complex configurations, use Jinja2 templates:
templates/interfaces.j2:interfaces {
{% for interface in interfaces %}
{{ interface.name }} {
description "{{ interface.description }}";
unit 0 {
family ethernet-switching {
vlan {
members {{ interface.vlan }};
}
}
}
}
{% endfor %}
}host_vars/sw1.yml:interfaces:
- name: ge-0/0/0
description: "Server 1 Connection"
vlan: "engineering"
- name: ge-0/0/1
description: "Server 2 Connection"
vlan: "engineering"
- name: ge-0/0/2
description: "Finance Workstation"
vlan: "finance"---
# apply_interface_config.yml
- name: Configure Interfaces from Templates
hosts: juniper_switches
gather_facts: no
collections:
- juniper.junos
tasks:
- name: Create configuration from template
template:
src: templates/interfaces.j2
dest: "{{ inventory_hostname }}_interfaces.conf"
delegate_to: localhost
- name: Apply interface configuration
juniper_junos_config:
load: merge
src: "{{ inventory_hostname }}_interfaces.conf"
format: text
comment: "Interface configuration via template"
confirm: 1
validate: yes
register: result
- name: Show configuration diff
debug:
var: result.diff_linesRun the template-based configuration:
ansible-playbook apply_interface_config.ymlCreate a playbook to run and capture operational commands:
---
# operational_commands.yml
- name: Run Operational Commands on Juniper Devices
hosts: juniper
gather_facts: no
collections:
- juniper.junos
tasks:
- name: Check interface status
juniper_junos_command:
commands:
- show interfaces terse
- show system uptime
register: cli_output
- name: Save output to file
copy:
content: "{{ cli_output.stdout }}"
dest: "./outputs/{{ inventory_hostname }}_interfaces.txt"
delegate_to: localhost
- name: Show interface summary
debug:
msg: "{{ cli_output.stdout_lines[0] | join('\n') }}"Run the operational commands playbook:
ansible-playbook operational_commands.yml---
# upgrade_junos.yml
- name: Upgrade Junos OS
hosts: juniper_routers
gather_facts: no
collections:
- juniper.junos
tasks:
- name: Check current OS version
juniper_junos_facts:
register: junos_facts
- name: Display current version
debug:
msg: "Current Junos version: {{ junos_facts.ansible_facts.junos.version }}"
- name: Upgrade Junos OS
juniper_junos_software:
local_package: "./software/junos-srx-20.4R3-S1.tgz"
reboot: yes
validate: yes
register: upgrade
when: junos_facts.ansible_facts.junos.version != "20.4R3-S1"
- name: Wait for reboot to complete
wait_for:
host: "{{ ansible_host }}"
port: 830
delay: 60
timeout: 600
when: upgrade.changed
- name: Verify new version
juniper_junos_command:
commands:
- show version
register: version_output
when: upgrade.changed
- name: Display new version
debug:
var: version_output
when: upgrade.changedRun the upgrade playbook:
ansible-playbook upgrade_junos.ymlAnsible can also be used for network compliance checking and audit:
---
# compliance_check.yml
- name: Check Security Compliance
hosts: juniper
gather_facts: no
collections:
- juniper.junos
tasks:
- name: Get security configuration
juniper_junos_command:
commands:
- show configuration security
register: security_config
- name: Check for SSH version 2
juniper_junos_command:
commands:
- show configuration system services ssh | display set
register: ssh_config
- name: Verify NTP configuration
juniper_junos_command:
commands:
- show configuration system ntp
register: ntp_config
- name: Generate compliance report
template:
src: templates/compliance_report.j2
dest: "./reports/{{ inventory_hostname }}_compliance.md"
delegate_to: localhost
vars:
security_data: "{{ security_config.stdout[0] }}"
ssh_data: "{{ ssh_config.stdout[0] }}"
ntp_data: "{{ ntp_config.stdout[0] }}"When automating Juniper devices with Ansible, you may encounter several challenges:
Ensure SSH and NETCONF are enabled on your Juniper devices:
# CLI configuration to enable NETCONF
set system services netconf ssh
set system services sshVerify NETCONF connectivity with:
ssh -p 830 netadmin@192.168.1.1 -s netconfUse secure authentication methods:
# Using Ansible Vault for credentials
ansible-vault create secrets.ymlAdd your credentials to the vault file:
ansible_user: netadmin
ansible_password: secure_passwordReference in your playbook:
- name: Secure Configuration
hosts: juniper
vars_files:
- secrets.yml
tasks:
# Your tasks hereRun playbooks with vault:
ansible-playbook -i inventory.ini playbook.yml --ask-vault-passAlways validate your playbooks:
ansible-playbook --syntax-check playbook.ymlTest playbooks in check mode first:
ansible-playbook playbook.yml --checkImplement proper rollback mechanisms:
- name: Configuration with rollback safety
juniper_junos_config:
load: merge
src: config.txt
confirm: 5 # Auto-rollback after 5 minutes if not confirmed
commit: yes
register: result
- name: Confirm commit if tests pass
juniper_junos_config:
confirm_commit: yes
when: validation_tests | successTo maximize the benefits of Ansible automation for your Juniper network:
ansible-juniper/
├── inventory/
│ ├── hosts.ini
│ └── group_vars/
├── playbooks/
├── roles/
├── templates/
└── ansible.cfgAnsible for Juniper provides a powerful framework for network automation that can transform how your organization manages its infrastructure. By starting with basic playbooks and gradually incorporating more advanced techniques like templates and roles, you can build a robust automation strategy that scales with your network.
The examples provided in this article serve as a foundation upon which you can build more complex automation solutions tailored to your specific needs. As you gain experience with Ansible and Juniper automation, you’ll discover new ways to improve efficiency, reduce errors, and enable your network team to focus on strategic initiatives rather than repetitive tasks.
By embracing network automation with Ansible for Juniper, you position your organization to better handle the increasing demands of modern network management while maintaining security, compliance, and operational excellence.
