Ansible: Use Playbook to deploy the next office

After deploying many offices manually, I started dreading the thought of another office deployment. Normally, you don’t learn anything new when deploying an office as the process is usually the same. Configure access and core switches and then set about configuring the firewalls everywhere in your production network to allow access to new users. That is, until I found Ansible. I was thrilled about Ansible when I first learned about it and since then I have used it numerous times to deploy offices seamlessly and with minimal hassle.

Not just new office deployments but you can use Ansible in conjunction with jinja templates for management of existing architecture along with any other task that requires configuration management over a range of devices. The key here is, the task must be repetitive, otherwise, you are just wasting your time.

Allow me to share a simple guide for you to automate your next office deployment below:


Install Ansible:

Simply parse yum install ansible and you should be able to download and install ansible on a linux host.


Ansible employs the use of playbooks configured in the form of YAML files that initiate tasks based on templates and variables to churn out configuration files.

The basic format is as follows:

  • Playbook
    • Roles
      • Tasks
      • Templates
      • Variables

In my example, I have chosen to call my playbook office.yml. This playbook file calls in three roles which are firewall, core switch and access switch respectively. Each role has a task that constitutes pinning the variables in the variable folder against the template to churn out a config file. Roles are executed sequentially so in my case, the office.yml playbook, when executed, produces firewall config, core switch config and configuration files for multiple access switches.

Example office playbook output:


Config files folder:

Setting up Ansible:

A typical office deployment requires the configuration of firewall, core switch and multiple access switches. To generate configuration files for any office deployment, all you have to do is change the variables in the variable file for each type of device, i.e. firewall, core switch and access switches and then re-run the playbook. You can obviously re-adjust this based on your network deployment.

Below, I have shown snippets from my own office deployment playbook. You can simply use my example to understand and create your own playbook.


A view of the ansible directory:

Configs is the name of the directory where the churned out configuration files rest and office template is the directory that holds the office playbook and all roles, tasks, templates and variables.

A view of the playbook called office.yml:

The three “- – – ” imply that his is a yaml file. The roles sub category defines the roles this playbook calls. Each role is just the name of the folder holding tasks, templates and variables for that type of network device.

You can have multiple roles called in a single playbook. In my example, you can see I have three roles defined:

As explained before, each of the above roles is a folder in it’s own right and contains the tasks, templates and variable folders as shown below:

Task folder:

A quick look at the task file produces the following output:

All this above task file does is locate template titled 3850.j2 in the template folder and run it against the variable file stored in the variable folder with variable list titled core_switches. The task file then produces the configuration file and deposits it in /home/rafay.rasool/ansible/configs/ folder.

Template folder:

A quick look at the template folder yields the following output:

The base config is what the task file will always prefer to use. This base configuration file contains all the configuration related to the core switch. However, the base.j2 file points to 3850.j2 where it gets its interface related information. The wisdom here is that for a different model of cisco switch we don’t need to duplicate configuration. We can simply create a new template identifying configuration which is different for that switch and proceed to dump that config in a jinja template file titled with the name of that switch’s model. This model name is then referred to in the task file. This results in reusability of the same base template for the core switch and reduces the amount of work required to manually create more templates with the same variables.

An example would be the use of cisco’s 3750 series switch as core switch for the next office deployment. All we would have to do is modify the task file with 3750 instead of 3850 and then make sure a jinja template is configured in the template folder titled 3750 that has all configuration in it that is different in 3750 series switches only. This way, ansible would use the base configuration which is similar in all cisco switches and refer to the directed model in the task file to fetch the correct config for the device in use.

A quick look at the base template produces the following output:

A quick look at the 3850 template yields the following output:

{% block interfaces %} points to a block of interfaces in another file. This file is the defined file in the task of the role which in the example is 3850.  {% extends “base.j2″%} in the 3850 file simply defines the extension of the base.j2 config file which is extended with the addition of all the config in the 3850.j2 template. Upon reaching the end of the 3850.j2 template file, ansible returns to base.j2 jinja template for execution of the remaining config in the template.

Variable folder:

The variable folder is where all the variables are listed that the task file picks and places inside the jinja template found inside the template folder. A quick look at the variable file produces the following output:

Each variable can be modified to a specified value and upon the next run of the playbook, this would impact the generation of the configuration.

Generating Configuration:

When tasked with an office deployment, all you need to do is modify the variable file in the firewall, core-switch and access-switch folder and then re-run the playbook. But before you can do that you have to define the variables first. These range from the IP schema to point to point addresses etc.

Therefore, lets say I want to churn out configuration for a new office with site code RMP-2. I would simply go ahead and open the variable file for the firewall and modify it as seen below:

Note: Remember to use CTRL+X and then press Y to save the config file when exiting if modifying the variable file using nano. For vi, its shift+zz

Similarly, a quick look at the vars file for core switch yields the following:

Moreover, a quick look at the vars file for access switch yields the following:

In case of access switches, each new line starting with a – denotes a new access switch. You simply need to change the sitecode details and update the management IP address in front of your management variable (in my example, it’s vlan20_ip) for each switch along with the gateway address. This is because the access switches are usually layer 2 switches with all layer 3 subnet addresses sitting on the core switch. If your deployment is different than modify as appropriate.

Once done, you are now ready to churn out office configuration using the office playbook inside the office-template folder.

Running the playbook:

To run the playbook all you need to do is go inside the office-template folder and pass the following command:

Once the playbook runs successfully without any errors, you can go back and view the generated configuration files which should be inside the ansible/configs folder:


Although Ansible reduces the time it takes to churn out configs, an IP Schema for your new office still needs to be defined and preferably uploaded onto an address management system such as Netbox before the variables inside ansible are modified.

It is easy to forget what IP address belongs to which vlan. A better naming convention in Netbox can help avoid this confusion.

Got questions? Leave a comment! Let’s chat.

Rafay Rasool is a Network Specialist with over 10 years of experience designing, configuring and implementing core network solutions based predominantly but not limited to Juniper Routers, Switches and Firewalls along with other vendors such as Cisco, Huawei, Siemens, Aerohive, Ringmaster, Pulse etc for Internet Service Provider and Enterprise Networks.

Rafay is an avid supporter of network automation and likes to code and automate networking solutions.