Ansible Logo


With the modern developments around Infrasture-as-Code and more specifically Networking-as-Code. There is a greater demand to understand the development, and deployment of network configurations through code such as Ansible.

Cisco has a great developer platform where you can learn more here.

Ansible is an automation platform that has been extended to support physical networks, software-defined networks and cloud based networks. Ansible is an automation pltform that is flexible and can be used across a diverse network of devices and domains, making it easier to automate your entire network and IT processes.

For installing Ansible we recommend starting here.

Ansible Galaxies

To make management of the cisco device easier. We will download the anisble ios module. From your shell/terminal simply execute the following:

ansible-galaxy collection install cisco.ios

Cisco Cloud Router CSR1000v

You will need a copy of the Cisco CSR 1000v virtual router this can be downloaded from the Cisco Website


Setup will not be covered here, but we assume you know how to setup VMware, Virtualbox, Qemu, or another suitable virtualisation platform.

Preparing the CSR Image

Before we can provision the state of the virtual router, we need to get it ready for Ansible. This means:

  • changing the host name
  • setup an initial IP address
  • enabling authentication
  • enabling ssh

Changing the hostname

Use the virtual console to access the terminal of the router and type the following commands:

conf t
no ip domain
hostname ios-ex1

Setup an initial IP address

conf t
interface GigabitEthernet1
 description Bridge Interface
 ip address dhcp
 ip nat outside

Enabling authentication

We assume you are continuing from the previous terminal state, so enter this sequence of commands:

Remember: make a note of your credentials we will need these later…

conf t
aaa new-model
aaa authentication login default local
aaa authentication enable default enable
username cisco secret 5 <password>
enable secret 5 <password>
line vty 0 4
login local
transport input ssh

WARNING: This is mearly just for out test-system and for self-learning, please use appropriate credentials in your own or your business’ enterrpise environments!

Setup SSH

Note: by default Cisco will use key bit length of 512 or 768 bits. But for OpenSSH (for our Ansible conenction), we need a minimal key length of 1024 bits.

conf t
crypto key generate rsa
ip ssh version 2

Last steps

Note: again the following commands make things easier in the lab, please dont use these in production!

Add the following to ansible.cfg:



Add the following to your ~/.ssh/config:

Host <ip of csr1000v>
 KexAlgorithms +diffie-hellman-group1-sha1 

We should now be ready to play with Ansible networking on the CSR1000v


You probably want to keep everything within a folder to keep things tidy in your workspace/shell. Create an appropriate directory and change directory:

mkdir ansible
cd ansible

If you want to know more about ansible and its work-tree/ directory layout we advise reading this page

Inventory File

Before we begin, you’ll need to create an inventory file and list some variables so ansible can connect to the new virtual CSR1000v image:

A basic invenotry file, is a tag, followed by the hostname and the ip address of the machine as follows:

ios-ex1 ansible_host=

For completeness, here is a copy of our test inventory file, refering to our test CSR1000v image

ios-ex1 ansible_host=

ansible_ssh_common_args: '-o KexAlgorithms=+diffie-hellman-group1-sha1 -o HostKeyAlgorithms=+ssh-rsa -o Ciphers=+aes256-cbc'

Ansible Ping

Test that Ansible can communicate with the machine:

ansible iosxe -m ping -i inventory.ini

Hopefully, you will get a success message like below:

ios-ex1 | SUCCESS => {
    "changed": false,
    "ping": "pong"

Initial Automation Script

We created the following path and main.yml file that will contain our sample task code:

mkdir roles/ios/tasks
vi roles/ios/tasks/main.yml 
- name: Configure top level config
  hosts: iosxe
  gather_facts: false

  - name: Configure hostname
        hostname: "\{\{ inventory_hostname \}\}"
      state: merged

  - name: Configure remove domain lookups
      state: absent

  - name: configure DNS lookup sources
      lookup_enabled: no

  - name: configure name servers

  - name: Remove uneeded banners
      banner: "\{\{ item \}\}"
      state: absent
    - motd
    - exec
    - incoming

  - name: Update login banner
      banner: login
      text: |
        | This banner was generated by Ansible 
        | You are logged into \{\{ inventory_hostname \}\}
      state: present

*Note: excuse the backslashes, we coudln’t get the yml file to render correctly in the css.

Execute our playbook:

❯ ansible-playbook -i inventory.ini --limit "ios-xe1" roles/ios/tasks/main.yml


PLAY [Configure top level config] ***********************************

TASK [Configure hostname] *******************************************
changed: [ios-xe1]

TASK [Configure remove domain lookups] ******************************
changed: [ios-xe1]

TASK [configure DNS lookup sources] *********************************
changed: [ios-xe1]

TASK [configure name servers] ***************************************
changed: [ios-xe1]

TASK [Remove uneeded banners] ***************************************
ok: [ios-xe1] => (item=motd)
ok: [ios-xe1] => (item=exec)
ok: [ios-xe1] => (item=incoming)

TASK [Update login banner] *******************************************
ok: [ios-xe1]

PLAY RECAP ***********************************************************
ios-xe1                     : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

You should now have everything to practise your ansible and ansible-networking provisioning before playing in the enterprise!

Share on: