Examples of how to use Ansible to create and apply Junos configuration
Switch branches/tags
Nothing to show
Clone or download
dgjnpr Merge pull request #2 from dulucky/bug-fix-common-template
Bug Fix for Common Role j2 template
Latest commit 589a323 Oct 24, 2016


Ansible version

This repository is designed to work with Ansible 2.1 and above. If you are using Ansible 2.0 or below please see this version of the repository.

The main diference between Ansible 2.0 and 2.1 is that the modules required to work with Junos devices are now bundled with Ansibe itself, have been renamed and had slight modifications to the options they support.

Ansible for Junos OS

This is an example Ansible configuration demonstrating how to use Ansible to generate and apply Junos configuration to the EX, MX, QFabric, QFX, and SRX Juniper platforms. Additional platforms will function in the same way (such as the ACX or PTX) but as yet have are included in this repository.

The configuration generated will enable system basics such as TACACS+ authentication, NTP, SSH, NETCONF, local and remote authenticated users, syslog, SNMP, a loopback and management interface.

The configuration generated by this example is not the complete configuration that can be applied to these platforms. It is expected that you will modify and extend the configuration to meet your own needs.

It is assumed that you have an understanding Ansible and how its structure works. If that is not the case, then please read through the Ansible Documentation.

There are many ways to use Ansible to generate and apply configuration to devices. This example is heavily documented to provide the reader with an explanation for the design choices made.


To be able to use the Ansible configuration you must have a copy of Ansible installed. The junos_* modules requires that Junos PyEZ is installed. Finally you must also install JXMLEase following these instructions.

Please review the installation documentation for the above to ensure all required dependencies are also installed. These dependencies are platform dependent. However the installation documentation should contain all the documentation you need.


With Ansible's flexibility, some choices have to be made. For some there are no clear right or wrong answers. Such decisions have been documented, either in this README or within the file - depending on where it is most appropriate.


Hosts File Structure

The Ansible hosts file is one of the most important files to get structurally correct. The structure used allows for global, location, function, and device specific data.

For further details, please see the comments in the hosts file.

Group Variables

The group_vars directory contains information appropriate globally, per site, and per platform. This is made possible by the structure of the hosts file.

For example the hosts file deines a site1 group. There is a corresponding site1.yaml file that deines site1 specific data.

Host Variables

The host_vars files contains device specific information for each of the devices listed in the hosts file. There must be one file for each host defined in the hosts file.


Playbooks are structured hierarchically. To have (syntactic) symmetry with the hosts file, the top playbook is the all.pb.yaml file. That playbook includes a playbook for each of the platforms.

Each platform playbook defines the roles to execute, merges the configuration fragments, and then applies the configuration if the configuration changed.

This structure takes advantage of Junos' ability to parse Junos' configuration even if the configuration is not in order. This feature makes creating Junos' configuration very simple in Ansible. This feature is used to break the configuration up into functional blocks that makes sense to the designer.

For further details, please see the comments in each of the playbooks.


Each of the roles just generates the configuration. Each role generates one or more configuration fragment that is merged into one file. Roles are made up of a task and one or more template file.

For further details, please see the comments in the roles/*/tasks/main.yaml files.


Templates are kept as simple as possible. The emphasis is to keep the Jinja2 constructs to the basic features. Jinja2 is a powerful templating system. To avoid overloading the reader with too many new concepts, the use of advanced Jinja2 operations is avoided as much as possible.

For further details about the Jinja2 templating operators, please see the comments in each of the playbooks.


To execute this example - and apply the configuration generated by this example - use the following Linux CLI command:

> ansible-playbook -i hosts all.pb.yaml

That will cause Ansible to run through all of the plays, generating and applying configuration for all the devices.

Limiting scope of execution

Ansible supports executing against a subset of the hosts. This is achieved with the --limit option. You can limit on either a hostname or a group name. For example, to only generate and apply configuration to all EXs in site 1 use the command:

> ansible-playbook -i hosts all.pb.yaml --limit site1_ex

To limit to a host supply the hostname, like this:

> ansible-playbook -i hosts all.pb.yaml --limit leaf1.site1.example.com

You can also limit execution by supplying a platform-specific playbook. For example, to apply changes to all MXs just use the mx.p.yaml like so:

> ansible-playbook -i hosts mx.p.yaml

You may also use the --limit option with this playbook.

Further Documentation

Please look through the rest of the files. All of them contain documentation relevant to their purpose.

How to Use

Fork this repo and edit the group_vars and/or host_vars files and the templates in the roles. Simply delete the platform specific plays from the all.pb.yaml file that you are not interested in.

You can delete the platform specific plays (i.e. ex.p.yaml) and roles directories too, but that is not mandatory. It just depends on how tidy you like to be.


  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request


David Gethings, Juniper Networks Follow Dave on Twitter