Using Ansible and the Juniper Junos module with KVM

Share on:

I started reading Automating Junos Administration, the Ansible chapter in specific, to get a start on automation. I will note a couple of things that were peculiar as I worked my way through. These are tips and failures that should affect anyone working through this chapter.

Junos supports several automation tools that provide powerful solutions to common network automation tasks. Whilst setting up the previous posts it was a cinch to write some playbooks and setup the initial configurations for multiple devices. It is worth spending the time to learn a little Ansible if you are provisioning many routers that share many of the same aspects of configuration.

Console Connections

In the chapter, when connecting to a console, this is done via a Terminal Server rather than a Serial Connection.

The terminal server must:

  • support Telnet connections, on a specific IP address and TCP port number, to reach this Junos device’s console.

  • require any additional authentication or authorization to access the console connection.

See "Junos Authentication and Authorization" of the Ansible chapter for more detailed information.

As I am using virtual Juniper devices under KVM this needs some explanation. By default KVM provides serial ports for the console. These are Pseudo Terminals and provisioned under /dev/pts/* with * being the number/instance of the pts. However, for the purposes of the chapter I will reassign these consoles to act as a Terminal Server. We do this with some XML fiddling so our relevant sections appear as follows:

<serial type='tcp'>
  <source mode='bind' host='' service='4555'/>
  <protocol type='telnet'/>
  <target port='0'/>
<console type='tcp'>
  <source mode='bind' host='' service='4555'/>
  <protocol type='telnet'/>
  <target type='serial' port='0'/>


If you choose to install via pip install junos-netconify, you will get a slightly out of date package with an error in the file. This throws a "list index out of range" error and basically means your console connections will not work with the junos_get_facts module. It should be changed to represent the following:

        # extract the version
        # First try the  tag present in >= 15.1
	swinfo = rsp.findtext('junos-version', default=None)
        if not swinfo:
            # For < 15.1, get version from the "junos" package.
            pkginfo = rsp.xpath(

Installing via the GitHub method should avoid this problem.


Hopefully this has been useful to someone out there and you can get on with your Ansible/Juniper journey.


junos-netconify has now been merged into PyEZ so when you read through the chapter...

  • you do not need to install junos-netconify

  • you will need to adjust the code to reflect the PyEZ way of doing things.

So what was: {% raw %} ... junos_get_facts: host: "{{ inventory_hostname }}" console: "--telnet={{ jaccess.console_ts }},{{ jaccess.console_port }}" user: "root" passwd: "{{ jaccess.root_password }}" savedir: tmp/ register: jresult ... {% endraw %} should appear: {% raw %} ... junos_get_facts: host: "{{ jaccess.console_ts }}" mode: "telnet" port: "{{ jaccess.console_port }}" user: "root" passwd: "{{ jaccess.root_password }}" savedir: tmp/ register: jresult ... {% endraw %}


This was an older post ( late 2016/early 2017 ) from my networkfoo github page, where I used to mess about with Juniper equipment. I have added it here just to keep everything all in one place and also that, someone may find it interesting.