Network Automation With Ansible

Ansible Overview

Hello folks, today I am going to share my latest experiment on network automation. In this article I will use Ansible as a tool for configuration management. So what is Ansible?, according to ansible website, “Ansible is a simple IT automation engine that automates cloud provisioning, configuration management, application deployment, intra-service orchestration, and many other IT needs. It uses no agents and no additional custom security infrastructure, so it’s easy to deploy – and most importantly, it uses a very simple language (YAML, in the form of Ansible Playbooks) that allow you to describe your automation jobs in a way that approaches plain English”.

Ansible is often used on server area especially on Operating System (OS) configuration and management. In this section I am going to share how Ansible does the configuration management and deployment on Intermediate devices (router).

CentOS installation

You can use any operating system to run an Ansible Playbook. In this demo I am using CentOS7. Before you start the installation, you need to install Extra Packages for Enterprise Linux (EPEL), please find the installation information here. The installation process is very simple. You may use below command to install Ansible on CentOS7

yum install ansible

Then verify the installation version using below syntax.

[root@terminal ~]# ansible --version
ansible 2.2.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides

Ansible have a lot of modules to interact with the remote systems. The one we interested here are the ios modules.

[root@terminal ~]# ansible-doc --list | grep 'ios_'
ios_command                        Run commands on remote devices running Cisco IOS                                                                                    
ios_config                         Manage Cisco IOS configuration sections                                                                                             
ios_facts                          Collect facts from remote devices running IOS                                                                                       
ios_template                       Manage Cisco IOS device configurations over SSH

For other Cisco OS families, you may check using ‘nxos_’, ‘iosxr’ keyword. Also you can find more modules in here. Check the latest version of Ansible for Linux here.

Ansible Directories

Once the installation finished, you may take a look on ansible directory. It has several files and a directory.

[root@terminal ~]# cd /etc/ansible/
[root@terminal ansible]# ls -l
total 28
-rw-r--r--. 1 root root 13817 Oct 20 14:10 ansible.cfg
-rw-r--r--. 1 root root    12 Oct 20 15:51 hosts
drwxr-xr-x. 2 root root     6 Jul 29 01:54 roles

I did two changes on ansible.cfg file. I have enabled log_path and ssh time out section.

# SSH timeout
timeout = 10
# logging is off by default unless this path is defined
# if so defined, consider logrotate
log_path = /var/log/ansible.log

The ansible.log records any activity when you run the ansible playbook. The second file you may focus is hosts file. This is your inventory list of your remote system devices. Mine is below:

[root@terminal ansible]# cat hosts 
[ios]
R1.mylab.net
R2.mylab.net

Or you can do it on Ansible way.

[root@terminal ~]# ansible all --list-host
  hosts (2):
    R1.mylab.net
    R2.mylab.net

I was created ios group consist of two devices R1 and R2. These are my remote system devices that I am going to manage. You may create several groups it is depends on your requirement.

Ansible Playbooks

Ansible uses Playbooks as configuration, deployment, and orchestration language. They can describes a policy you want your remote systems to enforce, or a set of steps in a general IT process. If Ansible modules are the tool in your workshop, playbooks are your instruction manual, and your inventory of hosts are your raw material. Ansible playbooks are written in YAML syntax. YAML is a file format similar in intent to JSON, but generaly easier for human to write and read.

Playbook Preparation

In this subsection we are going to prepare ansible playbook and do a simple configuration to remote systems using playbooks. I have created two additional files: credentials.yml it contain remote system user and password and playbook_acl.yml the playbook it self.

[root@terminal ansible]# cat credentials.yml 
---

secret:
    username: myname
    password: myname123
    auth_pass: myname123

This playbook purpose is creating an access-list and apply it to line vty. After the configuration is successfully implemented we also need to verify it on each configuration section.

[root@terminal ansible]# vim playbook_acl.yml 
---
- hosts: ios
  gather_facts: no
  connection: local

  tasks:
  - name: CREATE ACL FOR VTY ACCESS
    include_vars: credentials.yml

  - name: DEFINE PROVIDER
    set_fact:
      provider:
        host: "{{ inventory_hostname }}"
        username: "{{ secret['username'] }}"
        password: "{{ secret['password'] }}"
        auth_pass: "{{ secret['auth_pass'] }}"

  - name: CREATE ACL
    ios_config:
      provider: "{{ provider }}"
      authorize: yes
      lines:
        - permit ip 172.16.0.0 0.0.255.255 any
        - permit ip 192.168.1.0 0.0.0.255 any
      parents: ip access-list extended VTY_ACCESS

  - name: APPLY ACL
    ios_config:
      provider: "{{ provider }}"
      authorize: yes
      lines:
        - access-class VTY_ACCESS in
      parents: line vty 0 4

  - name: VERIFY ACL CONFIG
    ios_command:
      provider: "{{ provider }}"
      commands:
        - show ip access-list
    register: acl

  - debug: var=acl.stdout_lines


  - name: VERIFY LINE VTY CONFIG
    ios_command:
      provider: "{{ provider }}"
      commands:
        - show run | sec line vty
    register: vty

  - debug: var=vty.stdout_lines

Before we go further to the execution part. I will explain several information stated on the YAML file on the Ansible playbook.

  • hosts: – is the group device name on your hosts file
  • gather_facts – Any information spesifically owned by remote devices, some says device spesifications.
  • connection – type of connection to remote system.
  • name – Name of sub task activity, can be anything.

Let’s do final verification on remote system before we execute the playbook.

R1#sh ip access-lists 
R1#
R1#sh run | sec line vty 
line vty 0 4
 transport input ssh
 
R2#sh ip access-lists 
R2#
R2#sh run | sec line vty 
line vty 0 4
 transport input ssh
 

Playbook Demo

Now run the playbook using below command.

[root@terminal ansible]# ansible-playbook -i hosts playbook_acl.yml 

PLAY [ios] *********************************************************************

TASK [CREATE ACL FOR VTY ACCESS] ***********************************************
ok: [R2.mylab.net]
ok: [R1.mylab.net]

TASK [DEFINE PROVIDER] *********************************************************
ok: [R1.mylab.net]
ok: [R2.mylab.net]

TASK [CREATE ACL] **************************************************************
changed: [R1.mylab.net]
changed: [R2.mylab.net]

TASK [APPLY ACL] ***************************************************************
changed: [R2.mylab.net]
changed: [R1.mylab.net]

TASK [VERIFY ACL CONFIG] *******************************************************
ok: [R1.mylab.net]
ok: [R2.mylab.net]

TASK [debug] *******************************************************************
ok: [R1.mylab.net] => {
    "acl.stdout_lines": [
        [
            "Extended IP access list VTY_ACCESS", 
            "    10 permit ip 172.16.0.0 0.0.255.255 any (2 matches)", 
            "    20 permit ip 192.168.1.0 0.0.0.255 any"
        ]
    ]
}
ok: [R2.mylab.net] => {
    "acl.stdout_lines": [
        [
            "Extended IP access list VTY_ACCESS", 
            "    10 permit ip 172.16.0.0 0.0.255.255 any (2 matches)", 
            "    20 permit ip 192.168.1.0 0.0.0.255 any"
        ]
    ]
}

TASK [VERIFY LINE VTY CONFIG] **************************************************
ok: [R1.mylab.net]
ok: [R2.mylab.net]

TASK [debug] *******************************************************************
ok: [R1.mylab.net] => {
    "vty.stdout_lines": [
        [
            "line vty 0 4", 
            " access-class VTY_ACCESS in",  
            " transport input ssh"
        ]
    ]
}
ok: [R2.mylab.net] => {
    "vty.stdout_lines": [
        [
            "line vty 0 4", 
            " access-class VTY_ACCESS in", 
            " transport input ssh"
        ]
    ]
}

PLAY RECAP *********************************************************************
R1.mylab.net               : ok=8    changed=2    unreachable=0    failed=0   
R2.mylab.net               : ok=8    changed=2    unreachable=0    failed=0   

As you can see on above output. Tasks was executed orderly as we stated on the playbook_acl.yml file. At the bottom of the output we can se the summary of our activity. Don’t forget to verify our remote system if the configuration was properly implemented.

R1#sh ip access-lists 
Extended IP access list VTY_ACCESS
    10 permit ip 172.16.0.0 0.0.255.255 any (4 matches)
    20 permit ip 192.168.1.0 0.0.0.255 any
R1#
R1#sh run | sec line vty 
line vty 0 4
 access-class VTY_ACCESS in
 transport input ssh
 
R2#sh ip access-lists 
Extended IP access list VTY_ACCESS
    10 permit ip 172.16.0.0 0.0.255.255 any (4 matches)
    20 permit ip 192.168.1.0 0.0.0.255 any
R2#
R2#sh run | sec line vty 
line vty 0 4
 access-class VTY_ACCESS in
 transport input ssh

On the next post we will explore any other Ansible features, and how it help us as a network engineer.

Contributor:

Ananto Yudi Hendrawan
Network Engineer - CCIE Service Provider #38962, RHCSA, VCP6-DCV
nantoyudi@gmail.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s