Blog Viewer

Scripting How-To: Use Ansible to generate and apply Junos configuration

By Erdem posted 08-07-2015 23:30


Use Ansible to Generate and Apply Junos Configuration


This example demonstrates how to use Ansible to generate and apply Junos configuration to the EX, MX, QFabric, QFX, and SRX Juniper platforms.


The configuration generated enables 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 you can apply 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 of Ansible and how its structure works. If that is not the case, then please review the Ansible Documentation.


There are many ways to use Ansible to generate and apply configuration to devices. This example provides you with an explanation for the design choices made.




To use the Ansible configuration, you must have a copy of Ansible installed. In order to apply the configuration generated, you must have a copy of the Junos plugin for Ansible installed. The Junos plugin requires that Junos PyEZ is installed too. Finally install the Juniper Ansible role using `sudo ansible-galaxy install Juniper.junos`


NOTE: Please review the installation documentation for the above to ensure all required dependencies are also installed.




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.


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


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.


Additional Documentation


Please review 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