Monthly Archives: August 2016

Getting started with Ansible

Knowledge level: Basic *nix skills.
Pre-reqs: 2 machines, one to run *nix commands on, and one remote server / VM to install the app on to.

Background

Ansible is a configuration management and orchestration tool that helps you to provision, deploy, configure and update servers.

It allows you to automated deploys without requiring a client running on each server.

This is a simple guide to get you up and running quickly with Ansible. All you need two Ubuntu machines (they can be VMs) and some basic knowledge of running linux commands. The first machine is the controller machine, this is the machine we will execute the Ansible commands on. You will also need a second machine to practise installing software on to, either a remote machine or a VM that you have the log in details for and an SSH key pair set up on. If this machine is also Ubuntu then you will be able to use the following scripts as is without modification.

I’ve been working with Ansible for a while now and I really like it. I find it much easier to follow what will be run on remote servers at run time than Chef and as I don’t know Ruby that well I like that the logic is in the configuration files.

We are going to take a simple CRUD app built in Node.js and get it running on an Ubuntu machine using Ansible.

Setup

Ansible is very simple to get started with and has great documentation, this is one of the best things about it.

To install Ansible on your local machine which Ansible calls a controller machine you can use the following method for Ubuntu 16.04:

Ansible has a personal package archive, you can add this for apt-get to use

sudo apt-add-repository ppa:ansible/ansible

and then install it with

sudo apt-get update
sudo apt-get install ansible

Config

Ansible uses a hosts file to know what servers it can talk to. It uses SSH to connect to remote servers (it can be pointed at localhost too). This means it is building on the decades of secure engineering built into SSH to protect your communication with your servers. The most basic configuration is to list the IP address or DNS resolvable name of a server you own in the hosts file

[webserver]
server.example.com ansible_connection=ssh ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa

Add in the hostname of your server or the ip address, the username you can login with (it will need to be in the sudoers group as we need privileged access later) and your ssh private key location.

Aside: If you don’t want to use a public/private key pair to login to your server in order to get up and running quickly, you can run the ansible-playbook command with the flag —ask-pass and provide the ansible_user’s password at stdin when prompted.

Ansible allows you to create dynamic inventory files, which involves writing scripts that output the servers ansible should talk to. We will cover these another time, but for now it is much easier to get started with a static inventory file that just lists the IP address / hostname of the server you want to connect to and the user you want to connect as.

Once we have configured Ansible to talk to a server we need to tell it what to do.

Playbooks

Ansible uses ‘playbooks’ to list actions that should be taken against target servers. These can list packages to be installed, security updates to perform, configuration to be set up in different environments and processes to be run.

We will take the example of running a simple CRUD REST app using Node.js and express. You can take a look at the app at github.com/DistributedDeveloper/examples/tree/master/apps/REST/CRUD

We will install Node.js and npm, download the source code for the REST app to the target server, install the npm packages we need and all using Ansible. We can then login and run the app.

Instructions

Download a copy of the playbook from github.com/DistributedDeveloper/examples/blob/master/apps/REST/CRUD/playbook.yml

This file is in .yml format (called yaml format). Ansible has a ton of built in modules that allow you to perform common tasks on servers like running shell commands and capturing stdout or running docker containers.

We use a few here. Take the time to have a quick look at the playbook.yml. We

Target only ‘webservers’ from our hosts file.
Install Node.js using the Ansible apt module which uses apt-get.
Install npm so we can install node packages later.
Create the directory we want to save the app in.
Checkout the demo app git repo from github.
Install the pre-req packages for our node app.

Now to configure the server.

ansible-playbook -i hosts playbook.yml —ask-become-pass

That’s it. That’s all you have to do. Try it now!

This will connect to the hosts in your hosts file, that are labelled webservers, and run all the tasks in the playbook.yml against them. It will also ask you for your remote server’s user’s password. We could have created a more complex playbook to allow us to install Node.js and npm without this but for now this is fine.

Now log into your remote server and go to /home/ubuntu/apps

You should see the checked out git repo of a sample REST API app.

cd into the directory and run

npm start

You can now go to

http://remote.server.com/ping

and see your wonderful app running.

Next time we will see how to run the app using Ansible in a docker container so we don’t have to login to run it.