Intro

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.

Architecture

blog/ansible-from-the-start-to-the-beginning/ansible-architecture.svg

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.

  • Control Node Central point of configuration management
  • Managed Nodes Hosts to be managed
  • Inventory Record of managed nodes
  • Playbooks Set of actions to perform on managed nodes

The agent-less nature of Ansible is one of the reasons it is more popular than other configuration management systems within the networking community.

Lab Environment

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.

blog/ansible-from-the-start-to-the-beginning/ansible-start-to-begin.svg

Code versions used for this lab

  • Python - 2.7.5
  • Ansible - 2.2.1
  • Centos 7 - minimal 1511
  • Cumulus VX - 3.2.1

Installation

Ansible can be installed via a distributions package manager, pip or built from source.

YUM distributions can find ansible in the epel-release repository.

cmd
sudo yum install epel-release
sudo yum install ansible

APT distributions can find ansible in a PPA repository.

cmd
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.

cmd
# 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

Host Inventory

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.

file
# ~/ansible/inventory
[server]
lab-centos-01

[network]
lab-cumulus-01

[lab:children]
server
network
Note
Hosts in an inventory file can be grouped using [group-name] syntax.

Anisble Configuration

The below minimal configuration will allow for the control node to connect to managed nodes specified in the inventory file.

file
# ~/ansible/ansible.cfg
[defaults]
hostfile=inventory
host_key_checking=False
retry_files_enabled=False

Directory Structure

Create the ansible.cfg and inventory files under the ~/ansible directory and ensure you have the following directory structure.

cmd
# ~/ansible
ansible
├── ansible.cfg
└── inventory

First steps

Once ansible is installed there is an 'ad-hoc' mode that can be used to test connectivity.

cmd
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

  • - m Module to use (more on this later).
  • - u Username to connect with.
  • - k Ask users SSH password.
Note
The ping module is not ICMP ping, but rather just tests SSH is open and the user can login.

Another example with the ansible ad-hoc command is using the command module to run arbitrary commands on a managed node.

cmd
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.

Playbook

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.

cmd
---
# ~/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"]
Note
Playbooks use YAML syntax and the white space is significant.

There are a number of things to note in the playbook

  • --- Identifies the file as a YAML file. (Add to top of file)
  • hosts Declare which host(s) the tasks will run against. (network group in inventory file)
  • tasks List of 'plays' that will be executed. (Two play declared in playbook)

Playbook Execution

Playbooks are run with the ansible-playbook <playbook-name> [options] command

cmd
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

Outro

You should now have Ansible up and running on a control node and gathering information from a Cumulus Linux managed node.

Remember: This is not the end, it's merely the beginning!

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.