published: 11th of March 2017
Ansible is a configuration management platform that sits in the DevOps space along with Puppet , Chef and Salt Stack . Touted as being 'radically simple' its possible to get value from Ansible quite quickly with no programming experience required.
Ansible does not use agents to make configuration changes on devices, instead it relies on a push based method to send configurations to devices. There are four main components in the Ansible solution.
The agent-less nature of Ansible is one of the reasons it is more popular than other configuration management systems within the networking community.
The goal of this lab is to install and configure an Ansible control node and have it communicating with a managed node.
If you are following along at home we will use a Centos 7 minimal server as a control node and a Cumulus host as a managed node. For those unfamiliar with Cumulus Linux it is an open network operating system from the Debian family of linux.
Ansible can be installed via a distributions package manager, pip or built from source.
YUM distributions can find ansible in the epel-release repository.
sudo yum install epel-release
sudo yum install ansible
APT distributions can find ansible in a PPA repository.
sudo apt-get install software-properties-common
sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install ansible
PIP package is available for installation with pip . If using pip it is preferable to install ansible within a virtual environment.
# root user or user with sudo privileges
sudo yum install -y epel-release python-virtualenv gcc libffi-devel python-devel openssl-devel sshpass
sudo yum group install -y "Development Tools"
curl -O https://bootstrap.pypa.io/get-pip.py
sudo python get-pip.py
sudo pip install cryptography
# standard user
mkdir ~/envs
virtualenv ~/envs/ansible-env
source ~/envs/ansible-env/bin/activate
pip install ansible
# create ansible directory for configuration management
mkdir ~/ansible
cd ~/ansible
Managed nodes are recorded in an inventory file. As part of this blog I will use a static inventory file, it is also possible to dynamically create an inventory file from an external source such as a CMDB.
# ~/ansible/inventory
[server]
lab-centos-01
[network]
lab-cumulus-01
[lab:children]
server
network
The below minimal configuration will allow for the control node to connect to managed nodes specified in the inventory file.
# ~/ansible/ansible.cfg
[defaults]
hostfile=inventory
host_key_checking=False
retry_files_enabled=False
Create the ansible.cfg and inventory files under the ~/ansible directory and ensure you have the following directory structure.
# ~/ansible
ansible
├── ansible.cfg
└── inventory
Once ansible is installed there is an 'ad-hoc' mode that can be used to test connectivity.
ansible lab-cumulus-01 -m ping -u cumulus -k
SSH password:
# output
lab-cumulus-01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
The ansible ad-hoc command is really just for testing and not used that much in practice. The usage pattern is ansible <host-pattern> [options]. In the above example there are a number of options being used
Another example with the ansible ad-hoc command is using the command module to run arbitrary commands on a managed node.
ansible lab-cumulus-01 -m command -a "net show interface" -u cumulus -k
SSH password:
# output
lab-cumulus-01 | SUCCESS | rc=0 >>
Name Speed MTU Mode Summary
-- ------ ------- ----- -------- --------------------------
UP lo N/A 65536 Loopback IP: 127.0.0.1/8, ::1/128
UP eth0 1G 1500 Mgmt IP: 172.16.92.133/24(DHCP)
The -a argument flag specifies the command to send, note the command should be enclosed in quotes.
In Ansible a playbook is where you tie all the pieces together to perform actions on a host. The following example playbook uses the command module to run a command against a host and prints out the result.
---
# ~/ansible/show-interfaces.yml
- hosts: network
tasks:
- name: Get interface information from {{ inventory_hostname }}
command: net show interface
register: show_interface
- name: Print output of net show interface from {{ inventory_hostname }}
debug: var=show_interface["stdout"]
There are a number of things to note in the playbook
Playbooks are run with the ansible-playbook <playbook-name> [options] command
ansible-playbook show-interfaces.yml -u cumulus -k
SSH password:
# output
PLAY [network] *****************************************************************
TASK [setup] *******************************************************************
ok: [lab-cumulus-01]
TASK [Get interface information from lab-cumulus-01] ***************************
changed: [lab-cumulus-01]
TASK [Print output of net show interface from lab-cumulus-01] ******************
ok: [lab-cumulus-01] => {
"show_interface[\'stdout\']": "\n Name Speed MTU Mode Summary\n-- ------ ------- ----- -------- --------------------------\nUP lo N/A 65536 Loopback IP: 127.0.0.1/8, ::1/128\nUP eth0 1G 1500 Mgmt IP: 172.16.92.133/24(DHCP)"
}
PLAY RECAP *********************************************************************
lab-cumulus-01 : ok=3 changed=1 unreachable=0 failed=0
You should now have Ansible up and running on a control node and gathering information from a Cumulus Linux managed node.
The "from the start to the beginning" series aims to take you from nothing to getting you up and running. This is not meant to be a comprehensive guide, but should be enough to get you started on the journey.