Ansible Automation on Ubuntu 20.04 in GNS3

Ansible is a useful tool for automating tasks on various systems, including servers and network devices. It can be a little tricky to set up, but it’s ok once you get the hang of it. Today we’ll just try to get ansible installed on an Ubuntu 20.04 server and able to connect to another Ubuntu server, a Rocky Linux server, and a Cisco IOSv router.

Topology

Ansible in GNS3

Our simple subnet of 172.16.0.0/24 will hold a Ubuntu 20.04 server at the top at 172.16.0.1 acting as the ansible controller. The others will all be managed nodes, they don’t have ansible installed. Ansible uses python3 on Linux servers to execute various commands, and it’s not installed by default on Rocky Linux 8.5, so I installed it. I also added a firewall to the Rocky node to allow SSH in, which is how ansible connects to nodes. The SSH server has been enabled on the Cisco IOSv router as well.

Installation

Following ansible’s official installation instructions, this quick script will get it installed. Comments are inline:

#Create apt file for ansible
touch /etc/apt/sources.list.d/ansible.list

#Add ppa to above file
echo '
deb http://ppa.launchpad.net/ansible/ansible/ubuntu focal main
' >> /etc/apt/sources.list.d/ansible.list

#Add key for ppa
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367

#Update and install
apt-get update
apt-get install ansible

Ansible should now be installed!

Create inventory

The next thing to do is create an inventory file. Ansible keeps it’s config files in /etc/ansible, so we’ll start by writing a config to /etc/ansible/hosts. This file supports multiple formats, we’ll use yaml because I like yaml (don’t judge me!). This simple script (it’s just an echo command and redirect) will set up the hosts file:

echo '

servers:
  hosts:
    ubuntu:
      ansible_host: 172.16.0.2
    rocky:
      ansible_host: 172.16.0.3
  vars:
    ansible_python_interpreter: /usr/bin/python3  #specify python3 for ubuntu and rocky


routers:
  hosts:
    cisco:
      ansible_host: 172.16.0.4
      ansible_network_os: cisco.ios.ios                     #OS is Cisco IOS!
      ansible_connection: ansible.netcommon.network_cli     #connect to IOS via CLI, no python
      ssh_args: -oKexAlgorithms=+diffie-hellman-group1-sha1 #key exchange algorithm to support older IOS

' > /etc/ansible/hosts

Verify inventory connections

The below command will check the integrity of your inventory (hosts) file:

ansible-inventory --list -y

Then once you have worked out any inventory file issues, “ping” your hosts. This is not an ICMP echo-request/echo-reply (commonly known as ping), ansible will actually try to log in to each host via SSH. Ansible assumes you have SSH public/private key pair authentication enabled, but since this is in a test environment in GNS3 we’ll just pass the user and password to ansible on the command line:

ansible all -m ping --extra-vars "ansible_user=james ansible_password=james"
---

ubuntu | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
rocky | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
cisco | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

With this, we’ve verified that we have configured our hosts and can properly connect to them from the controller.

Next we’ll try to make some changes with playbooks! Hope you liked this one.