Ansible for Beginners: Manage cisco router with ansible playbook



In my previous post I have shown you what playbook is, how to write and how you can run playbook. In this post I’ll show you another playbook which will be used for managing a Cisco router.  I’ll use the below simple topology for this tutorial. (All files used in this lab can be found here)

If you are new to Ansible then its better to check my other article “Ansible for Beginners: Introduction and Installation” and “Ansible for Beginners: Playbook” before continuing with this article.

Prepare the router

Ansible need ssh connection to communicate with the managing device, So ssh need to configured in our router. I use GNS3 in this lab and a Cisco 3745 router image. Perform the below steps to configure SSH on the router.

Router(config)#hostname trainigrouter
trainigrouter(config)#ip domain-name training.local
trainigrouter(config)#crypto key generate rsa

The name for the keys will be:
Choose the size of the key modulus in the range of360 to 4096for 
your General Purpose Keys. Choosing a key modulus greater than 
512 may take a few minutes.
How many bits in the modulus [512]: 2048
% Generating 2048 bit RSA keys, keys will be non-exportable...
[OK] (elapsed time was 10 seconds)

*Nov 16 07:11:59.495: %SSH-5-ENABLED: SSH 1.99 has been enabled
trainigrouter(config)#ip ssh version 2

Allow SSH access to the router:

trainigrouter(config)#line vty 0 15
trainigrouter(config-line)#login local
trainigrouter(config-line)#transport input ssh

Let’s create the user now:

trainigrouter(config)#username <YOUR_USER_NAME> secret <YOUR_SECRET_PASSWORD>

We will use this user for connecting the router from Ansible host. Try to make an ssh connection from your Ansible host to your router using the user you just created. it should connect.

The hosts file

The hosts file is the place where Ansible looks for the nodes which it needs to manage. In this file you tell Ansible that these are my hosts or nodes and your (Ansible) job is to manage this hosts. Create a directory called inventory and make a file called hosts inside that directory.

writeimtiaz➜~/blog» mkdir inventory
writeimtiaz➜~/blog» cd inventory
writeimtiaz➜~/blog/inventory» touch hosts

Now open the file with your favourite editor and add our router information in that hosts file like below.

router_a ansible_host=

(assume my router IP address is Save and exit from that file. Now exit from inventory directory and create the playbook.

The Playbook

Open a file name playbook.yml with your favourite editor and type the bellow line in that file. It’s a yml file so you should be careful about the space.

- hosts: router_a
  gather_facts: no
  connection: local

     include_vars: secrets.yml

         host: "{{ ansible_host }}"
         username: "{{ creds['username'] }}"
         password: "{{ creds['password'] }}"
         auth_pass: "{{ creds['auth_pass'] }}"

   - name: SET IP ADDRESS
       provider: "{{ provider }}"
       authorize: yes
       parents: "interface FastEthernet0/1"
         - description SOUTH-CUSTOMER
         - ip address
         - ipv6 address 2001:db8:2001::9/64
         - no shutdown

       provider: "{{ provider }}"
       authorize: yes
       save: yes
       backup: yes

Let me explain the playbook to you. In this playbook we have one play and four tasks. The file start with three dashes (—) means its a yml file. Then we told ansible that run this play against the router_a host, which can be found on our hosts file. During runtime ansible collect host information from the remote devices like host name. host type, os version, ip address etc which is called facts. Here we are telling Ansible that we don’t want any facts from our remote device. instead of running on the device we tell ansible run it locally.

We have four tasks in this file, the first task is “OBTAIN LOGIN INFORMATION” where I show you how you can include other yml file in your playbook. In our case we add secrets.yml file, we will create the file shortly. In this file we will put our username, password etc.

Our second task name is  “DEFINE PROVIDER“. provider is a collection of arguments used to define the characteristics of how to connect to the device. You can put your hostname, username, user password, auth password inside provider and when require you can call this provider.

Our third task name is “SET IP ADDRESS“. In this task we call ios_config module. To configure Cisco router with ansible we can use this module. This time we will use this module to configure the router interface. You can see that we call our provider in this task. For configuring IP address in the router you should be in privileged mode. authorize: yes is actually giving you that permission.

Our final task is “SAVE & BACKUP CONFIGURATION“. This task is simply saves the running configuration and take a backup on your local drive.

secrets.yml file

It’s time to create the secrets.yml file. You can give any other name if you like. Create the file and open it with your favourite editor and type the below line. Again, it’s a yml file so indenting should be handle carefully.


  username: "<YOUR_ROUTER_USERNAME>"
  password: "<YOUR_PASSWORD>"
  auth_pass: "<YOUR_AUTH_PASSWORD>"

Run the Playbook

Our playbook is ready and for running the playbook all other supporting files are ready now it’s time to run the playbook. You can check the syntax and can make a dry run before the final run. For run the palybook type the bellow command in your command line.

ansible-playbook -i inventory playbook.yml
PLAY [router_a] ********************************************************************************************************

TASK [OBTAIN LOGIN INFORMATION] ****************************************************************************************
ok: [router_a]

TASK [DEFINE PROVIDER] *************************************************************************************************
ok: [router_a]

TASK [SET IP ADDRESS] **************************************************************************************************
changed: [router_a]

TASK [SAVE & BACKUP CONFIGURATION] *************************************************************************************
changed: [router_a]

PLAY RECAP *************************************************************************************************************
router_a : ok=4 changed=2 unreachable=0 failed=0


If you see the output like above, then it’s working. Your script is running without any error. Notice the last line where you will find a play recap where failed=0 means it’s working. Go to your router and check your configuration. The IP address should be configured in the mention interface. (In my case I have Interface FastEthernet0/1 but you may have other interface. Change the interface and the IP address according to your environment.)

This is how you can manage a router with Ansible. This playbook which I have shown here is kind of a static thing, because if you need to use it again you have to edit the main script playbook.yml. You can make this script more robust and more dynamic with the help of Ansible role. In my next post I’ll show you how you can make ansible role using the same scenario.

Thanks for reading the post. If you enjoyed the post, please share it with your network and let me know your thoughts in the comments. 

About the Author: Imtiaz is working in a financial organization in Bangladesh and having experience in system, network and security administration. Feel free to contact with him on LinkedIn or Twitter


  1. Gerry

    Great site and thank you!. I hope you may be able to assist with:
    I receive the following error when running your playbook:
    TASK [test] *********************************************************************************************************************************************************************************************************************************
    fatal: []: FAILED! => {“ansible_facts”: {“discovered_interpreter_python”: “/usr/bin/python”}, “changed”: false, “msg”: “show running-config\r\nshow running-config\r\n ^\r\n% Invalid input detected at ‘^’ marker.\r\n\r\nS-TWN-TST01#”}

  2. Assalam o alaikum,

    Thanks for this post. I found it very useful. A lot of the posts related to configuring Cisco routers via Ansible either contain old and outdated content, or the text is not formatted properly as a valid YAML file. Keep up the good work and stay blessed!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back to Top
%d bloggers like this: