By Greg Trasuk on March 23, 2017

Introduction to Ansible

Ansible is a configuration management tool. It allows you to manage the configuration of a machine. When we say ‘machine’, we mean an operating system instance, whether that happens to be a desktop machine, server, or a virtual machine running in the cloud.

Ansible is one of a set of configuration management tools that has emerged over the past few years. Other popular options include Chef, Puppet, and SaltStack. Ansible is unique among these in being ‘agentless’: You don’t need to install ‘agent’ software on the nodes that you’ll be managing. Ansible only requires that the node is reachable over secure-shell (ssh). It also requires that the node can run Python 2.4, but that can actually be installed by Ansible itself if required.

Ansible runs on a “control node” , and works by constructing small programs called ‘modules’, and then sending them to the target machine (the “managed node”) over ‘ssh’ for execution.

Installing Software Ansible

To install software with Ansible, we’re going to need a few things:

  1. An “inventory” file, that lists all the nodes we are managing.
  2. A “playbook” file, that details the set of steps that Ansible should run on the managed nodes.
  3. Whatever identity keys we need for ‘ssh’ to be able to connect with the managed nodes.
  4. (Optional) A configuration file for Ansible itself, to configure any options that we need.
  5. The software we’re installing. This may come from a standard packaging system like ‘apt’ or ‘yum’, or could be downloaded from a local binary repository. It could even be source code that we check out of a source code management system.

We might even have a combination of software sources – it’s common to install Linux programs by compiling from source code, but we might need to have some set of development packages pre-installed on the machine. In this note, we’ll just install out of the standard repository.

Installing Ansible

Ansible’s documentation is generally pretty good. Refer to the [installation guide] (https://docs.ansible.com/ansible/intro_installation.html for instructions on how to install Ansible.

Set Up the Playbook Directory

Create an empty folder to contain our playbook and hosts file:

mkdir kb024

The Inventory File

Ansible requires a list of nodes to manage. This will be a file called ‘hosts’ in our playbook folder. Clearly we don’t want our playbook file to refer directly to machines; the assumption is that the list of machines will change over time – that’s why we’re automating this, so we can run the same installation again on different machines. So the way to do this is to define groups of machines, like so:

[tomcat_servers]
ec2-54-90-164-237.compute-1.amazonaws.com

As you can see, we’re using an Amazon EC2 instance for this sample.

We also might want to set some variables on the instance. Ansible will need to know if it should transform to root-user when it runs its modules, and if so, what method to use. Since this information is more to do with the type of instance than the type of software we’re installing, we can create another group, to represent the common features. So, we can add the following definitions to our ‘hosts’ file:

[ec2_linux]
ec2-54-90-164-237.compute-1.amazonaws.com

[ec2_linux:vars]
ansible_become=true
ansible_user='ec2-user'
ansible_become_method='sudo'
ansible_become_user='root'

Test the Communications

At this point, we should see if we can actually talk to the managed node. Ansible has a ‘direct’ mode that will let us run simple commands on the managed nodes. Before we can do that, we’ll need to setup the ssh keys so that we can talk to the node. That’s out of scope for this guide, so we’ll assume that we have a public key setup on the node, and we have a ‘.pem’ file that contains the private key that we need (this is the default for new Amazon instances – when you setup the instance it will offer you the chance to create a new key pair and download the private key).

There are a few ways to make the key available to ‘ssh’ for use by Ansible. In this example, we’ll use the ‘ssh-agent’ technique and add the key into the set managed by ‘ssh-agent’.

ssh-agent
ssh-add mykey.pem

Now, we can try a simple Ansible command.

ansible -i hosts -m ping all

With a bit of luck, you get output something like this:

ec2-54-90-164-237.compute-1.amazonaws.com | SUCCESS => {
 "changed": false,
 "ping": "pong"
}

Create a Playbook to Install Java

Often you’re using Ansible to manage a group of machines at a given site. So, let’s create a file called ‘site.yml’. This file will be formatted in the “YAML” markup language (http://yaml.org/).

A top-level playbook is formatted as a list of tasks that Ansible will execute across all the hosts in inventory. Each task will reference a module, providing a set of parameters for that module. We can also apply a ‘hosts:’ key to narrow down the set of hosts that the task should be run on. Each task should have a ‘name’ key that Ansible can print out to let us know what’s going on.

Ansible uses ‘modules’ to execute commands on the managed nodes. One module is the ‘package’ module, which will load packages using the system’s standard package manager.

Putting all this together, let’s load a Java Development Kit on our using the package manager. Put the following into ‘site.yml’:

---
- hosts: tomcat_servers
 tasks:
 - name: Install Java
 package: name='java-1.8.0-openjdk' state=latest

Now we can run the playbook using the ‘ansible-playbook’ command.

Gregs-MacBook-Pro:kb024 trasukg$ ansible-playbook -i hosts site.yml

PLAY [tomcat_servers] **********************************************************

TASK [setup] *******************************************************************
ok: [ec2-54-90-164-237.compute-1.amazonaws.com]

TASK [Install Java] ************************************************************
changed: [ec2-54-90-164-237.compute-1.amazonaws.com]

TASK [Select Java 8 in alternatives] *******************************************
changed: [ec2-54-90-164-237.compute-1.amazonaws.com]

PLAY RECAP *********************************************************************
ec2-54-90-164-237.compute-1.amazonaws.com : ok=3 changed=2 unreachable=0 failed=0

The “PLAY RECAP” section shows that we had no failed tasks. If you login to the machine, you’ll be able to check that Java is installed:

[ec2-user@ip-172-31-31-181 ~]$ java -version
openjdk version "1.8.0_121"
OpenJDK Runtime Environment (build 1.8.0_121-b13)
OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)
[ec2-user@ip-172-31-31-181 ~]$

Conclusion

As we can see, the basic task of installing software packages with Ansible is pretty straightforward. In this note, we’ve seen how to create an inventory file, check the communication with managed nodes, and install software using the package manager module.