Ansible Tower POC

As promised in a previous post, I suggested I would take a look at Ansible Tower as the front end to the Ansible engine and having demoed it at a recent work presentation for network automation and POC purposes, I thought I would document it here for posterity. I reused a previous lab I had built with virtual Dell OS10 devices, the details of which you can refer to here:

Tower installs via a simple script, the details of which, I won’t get into here, suffice it say, it took a few attempts and some dependencies to be installed, but after 4-5 attempts it finally installed. After the install you are presented with the login screen:


After successful login with the default username of admin, you are presented with the dashboard which gives you a one pane of glass view of your job status as a graph, recently used job templates (which are basically a wrapper for your playbooks) and recently run jobs and their completion status:


As a front end to the Ansible engine, I found Tower to be easy to navigate and not cluttered or busy with too many knobs and buttons, which can be the case with many enterprise grade configuration management tools. The interface was very simple.

Everything in Tower starts off life as a project, which is the housing for your playbooks (the meat and potatoes of your automation scripts). The section to note on this page is the method from which you “pull” or “source” your playbooks. This can be from a number of sources as displayed in the graphic below:


We have several options from which to source our playbooks, including Git, Subversion, Red Hat Insights and the one I chose –  manual, as I had the playbooks local to my Ansible control server.

The next tab over is the Inventory tab, which points Tower at your source for device identification. Again I went static on this and just pointed it at my hosts file in the root of my playbook directory. You can, through the API of Tower access dynamic inventory, from IPAM systems and other 3rd party tools.


After this tab, we have the templates page, which is where most of the construct is built from which the jobs we want to run are sourced.


We get an overview of the templates in the system and can click into each one for more details pertaining to that job template:


In here we get information regarding the name of the job template, the inventory it is sourcing for targeting devices, the CLI credentials required to gain access to the device, the project source mentioned previously, the playbook (in this case show_connection_status.yml) and some other settings that offer optimizations in how the tool handles processing the job, such as fact cache which Ansible define as follows:

“Tower can store and retrieve facts on a per-host basis through an Ansible Fact Cache plugin. This behavior is configurable on a per-job template basis. Fact caching is turned off by default but can be enabled to serve fact requests for all hosts in an inventory related to the job running. This allows you to use job templates with --limit while still having access to the entire inventory of host facts”

As you can see I have needle nosed my blast radius for the job by using a limit on the targeted devices to 2 spines and 3 leafs. As stated above fact caching enhances the limit functionality allowing you to use the limit option while still having access to the entire inventory of host facts. One last interesting point to note on this tab is the “job type” listed in the top right hand corner which classifies the job as either a run job or a check job:


This in effect, allows jobs to be setup in read-only mode for your NOC teams that you require to run checks on the network without necessarily allowing them to make changes.

Finally we have the jobs tab, which gives a broad overview of the success or failure of any job runs we have rolled out in the environment:


We can run a job by clicking on the rocket icon to the right of the job:


We can then access the job by clicking on the job itself from this view:


Tower gives a nice display screen from where we can easily see details of the job/playbook run. To the left we get a sidebar status of the job, including whether the job ran successfully, the start and end date, the template used, the user who launched the job, inventory, playbook name, credential details used for accessing the device, forks (amount of parallel processes Ansible uses on device access), limits, tags and any extra variables we may want include at run time. To the right we get a nice console output to the screen, of the playbook details, including task names, timestamps, output from included playbook directives, and a completion summary/recap when the job ends.


In summary, I have found Ansible Tower a very compelling addition as a workflow tool to the Ansible engine, and I would highly recommend it as a tool that could be leveraged in Enterprises thinking of using Ansible in production to manage their networking and server environments. As it is licensed on a per node basis, the larger the network, the more expensive it could become to manage it with Tower. But having said that, the costs can be offset by the benefit of reduced TCO and hours spent on manual configuration and troubleshooting in those environments where no downtime is critical. It is a tool that sits nicely in the world of DevOps and NetDevOps……………..

Cisco IOS WAN standards configuration and maintenance with Ansible

As part of a recent automation POC project at work, I was tasked with doing a demo of how Ansible could be used to configure a standard configuration to some WAN routers. In setting up the demo, I have used some IOSv virtual routers running 15.4 code a and control Ansible server built on Ubuntu server 16.0 LTS, all running on top of my laptop inside VMWare Workstation.

To demonstrate the concepts I setup 8 edge routers plugged into 2 separate service providers to mimic what we have in production.


To simulate the MPLS clouds, I used another virtual router with multiple VRFs and multiple BGP ASes using the local-as feature to mimic the 2 provider peerings.

My Playbook structure consists of the following layout, where I breakout each part of the configuration into separate roles as is best practice in most production setups of Ansible.


One of the key requirements of the POC was modifying a standards QOS policy applied to the routers. Each circuit has different bandwidth settings and hence different shaper settings for the WAN interface. I achieved this by modifying the Jinja template under the QOS role to take the interface bandwidth and multiply it by 3 places as Cisco uses different measurements under the interface bandwidth setting and QOS shaper setting. One is kilobits/sec, the other is set in bits/sec.


The qosbw variable refers back to a value in the host_vars folder where a yaml data file exists for each WAN router.


The WAN deployment playbook configures various different aspects of the router configuration, including interfaces, host names , syslog, ntp, routing protocols and vrf definitions.


An interesting task in the run book is the application of public keys from the control server to  the routers to facilitate running “raw” commands against the devices to quickly check configuration status post checks. This is required to get Ansible in ad-hoc mode commands to work against the routers as an SSH trust is needed for this to work. As part of the public key task, a write to memory is also required on the router in order for the router to save the Ansible server’s public key to its non volatile memory. After this is configured on the router, you can then issue quick mode commands against the device without the need to run a whole playbook.


This is a very handy feature to check quickly the status of a config on many different devices without the need to log into each router separately.

There is also two playbooks that check BGP and save the running config to various folders on the control server.


The BGP playbook first shows the output of two commands, displays them to the screen and then saves the result of standard out to a file and pops it in a local directory on the Ansible control server.


The Save running playbook does something similar and saves the results to a file in a local directory also for later reference. By setting a terminal length of 0 and then issuing a show run, we get a clean snapshot. Passing this to a register directive we can then do a copy of the content of standard out and send it to a file using the dest keyword as seen below:


Finally we can see the resulting files saved in the directories on the Ansible Server, designated by their host names.


And doing a cat of the contents we have a record of the routers configuration:



Next up I will be looking at Ansible Tower….stay tuned!