Ansible: A Basic Introduction

Learn the basics of an open-source, server provisioning tool

Published on
6 min read
Ansible: A Basic Introduction

Introduction

Ansible is a server provisioning tool, written in Python,  which allows you to manage several servers in an automated fashion. This makes the process of configuring and managing servers far simpler and more efficient. Moreover, it reduces the likelihood of making mistakes.

For example, Ansible can be used to:

  • Install, configure and deploy software
  • Configure systems (with users, packages etc)
  • Perform application deployment and system updates.

 
There are a few key points about Ansible to understand. 

  • Ansible uses OpenSSH to connect to each server
  • Ansible uses playbooks configured in YAML which act as code to provision the system
  • Ansible uses the control and managed node architecture

This means only OpenSSH must be installed and configured on each target node (server). However, the control node must have Ansible installed. 


Configuring Ansible

To use Ansible, and allow the control node to connect to each server, you'll need to set up a secure public/private key pair.

This can be done like so:
ssh-keygen -t ed25519 -C "ansible-keypair" 


Next, add the public key to all target nodes. This can be done using the ssh-copy-id command.
ssh-copy-id -i ~/.ssh/ansible.pub SERVERIP

Using the private key, you can now use this command to log in.
ssh -i ~/.ssh/ansiblekey SERVERIP 


To test that Ansible is working, you can send a ping to all servers using the ping module. This checks the connection of all servers, described in the inventory file.

The inventory file simply lists all the servers (via IP addresses or domain names that Ansible should connect to). For example:


[all-hosts]
192.168.0.11
192.168.0.12

Checking connections 

We can check the remote connection using the ping module in Ansible. We specify the private key, the inventory file and which hosts to conduct the ping:

ansible all --key-file ~/.ssh/ansiblekey -i inventory -m ping

However, this command is a little long. We can reduce this by creating an ansible.cfg file within our working directory. Within this file, we can specify where our inventory file is located, add our (server list) and private SSH key file, like so:



touch ansible.cfg

# Within ansible.cfg
[defaults]
inventory = inventory
private_key_file = ~/.ssh/ansiblekey

Now we can simply use:

ansible all -m ping 

We can also get a list of all the hosts:

ansible --list-hosts all 


# Output
hosts (2):
  192.168.56.11
  192.168.56.12

Gathering facts

Before each playbook is run, Ansible will typically 'gather facts'. This simply means that Ansible is gathering information about each server. This information can be used later in playbooks.

To gather information about each server, we can use the gather-facts module:

# For all machines
ansible all -m gather_facts

# For a particular machine
ansible IP -m gather_facts

# OR

ansible all -m gather_facts --limit IP


The --limit option allows you to only gather information about a certain node.


Automation

Let's imagine we wanted to update the cache for all our Debian servers. Doing this manually would mean logging into each server and performing the same commands. This is simply impractical - imagine if we had hundreds of servers!

Ansible has a few package management modules, one of them is the apt module. 
For example, we can update the apt cache repository. However, this command requires sudo privileges.

To get around this, we can use the --become & --ask-become-pass flags.
These flags allow an unprivileged user to 'become' root; the second option simply asks for the root password.

For example, we can:







  • Update the apt package cache

ansible all -m apt -a update_cache=true --become --ask-become-pass 

  • Install a package via the apt module

ansible all -m apt -a name=PACKAGENAME --become --ask-become-pass

  •  Ensure a specified package is on the latest update

ansible all -m apt -a "name=PACKAGENAME state=latest --become --ask-become-pass

  • Perform an upgrade on apt systems
    ansible all -m apt -a "upgrade=CHOICE" --become --ask-become-pass 

    Here, the -a flags allows us to perform ad-hoc commands; simply issuing commands as you would if logged onto a Linux system. This however is not the intended way to use Ansible. This is where playbooks come in.



Playbook 

Ansible uses playbooks to automate tasks. Each playbook has a play, which in turn has tasks. Multiple tasks can be run within a play.

Below is an example playbook to install apache2 on all nodes.

---
- hosts: all
  become: true
  tasks:

  - name: update repository
    apt:
      update_cache: yes
    when: ansible_distribution = "Ubuntu"

  - name: install apache2 server
    apt:
      name: apache2
    when ansible_distribution = "Ubuntu"


Here, we are specifying which hosts (nodes) in the inventory file to run this playbook on and whether we should 'become' root. Next are the listed tasks to conduct on each server. 

We set a name for the tasks, and include the appropriate module name. In this case, apt as we want to update the repository cache on all the Debian-based machines. We set the option update_cache to yes and set a conditional. 

This is where gathering_facts comes into play. Ansible will procure the distribution for each node and store it. So when this playbook is executed, we can use a conditional to determine whether or not to execute a task.

We can also add multiple distributions using a Python list in the when condition
Let's say we had Ubuntu & Debian machines to manage (which both use apt). We can do:







- name: update repo
    apt:
      update_cache: yes
    when: ansible_distribution in ["Debian", "Ubuntu"]

Executing playbooks

To execute a playbook, we can use the following command:

ansible-playbook 

For example, to run our apache2 playbook, we can issue this command:

ansible-playbook --become --ask-become-pass apache2.yml 

The name of the playbook can be any arbitrary value; however, it must be a YAML (.yml) file. If no errors occur, Ansible will gather facts and run the tasks on the machines specified within the playbook.


Conclusion

This post describes and explains very basic usage of Ansible, and how it works. Advanced usage of Ansible will be shown in further blog posts.

However, to re-iterate:

  • Ansible is a server provisioning tool
  • Ansible uses OpenSSH
  • Ansible uses playbooks, plays and tasks to perform automated server configuration and management.

Infrastructure-as-code (IaC) provisioning tools like Terraform and Ansible allow administrators  and engineers to automate mundane tasks; saving time and increasing productivity. Ansible is a great skill to have not only in a work environment, but also in a homelab setting too.

Author

Discussion (0)

Subscribe