A first look at Ansible

By Curtis Collicutt, Cloud Developer, Edmonton

In the modern world of Open Source configuration management, there are two 800lb gorillas (usually there'€™s only one 800lb gorilla, so we'€™re lucky actually to have two): Chef and Puppet.

But what else is out there? What if we don'€™t want two 800lb gorillas mucking up the place, breaking Grandma'€™s china plates, putting their feet up on our brand new coffee table and eating the last of the cheezies? What if we want to quickly start working with configuration management without having to set up centralized servers or bootstrap clients? One possible solution is Ansible.

I want to note that while I'€™ve been aware of Ansible for a couple of months, this is actually the first time I'€™m using it to deploy a system. So it really is a first look.

What is Ansible?

Here'€™s how Ansible defines itself:

Ansible is a radically simple model-driven configuration management, deployment, and command execution framework. Other tools in this space have been too complicated for too long, require too much bootstrapping, and have too much of a learning curve. Ansible is dead simple and painless to extend. For comparison, Puppet and Chef have about 60k lines of code. Ansible'€™s core is a little over 1,000 lines. – http://ansible.github.com/

As a career Unix/Linux systems administrator, one thing I look for in software is simplicity. Ansible counts simplicity as its major feature. I like that.

Another thing I look for is for reuse of existing (especially secure) tools. Instead of designing/coding/running its own client-side public key infrastructure daemon, Ansible (re)uses SSH.

While most configuration management tools use a daemon, running as root with full access to the system, with its own in-house developed PKI infrastructure, Ansible just uses SSH (and supports sudo as necessary). – http://ansible.github.com/

SSHD is one of the mostly widely used and secure servers in the world, so why not build on that instead of writing additional code?

Installing Ansible

Installing Ansible can be as easy as a git checkout. However, I'€™m going to take it a step further and build an RPM. (Note that installing Ansible from RPM is not necessary, but because I believe that properly deploying software is important, I'€™m going to do it via RPM. Otherwise I will be in trouble…with myself.)

Fortunately Ansible supports creating an RPM '€œout of the box.'€

On my CentOS 6.2 RPM build box I will build and install Ansible.

$ cat /etc/redhat-release
CentOS release 6.2 (Final)
$ cd ~/working
$ git clone git://github.com/ansible/ansible.git
$ cd ansible
$ make rpm
SNIP!
#############################################
Ansible RPM is built:
   rpm-build/noarch/ansible-0.5-1.el6.noarch.rpm
#############################################

Now to install that RPM. Note that I have the EPEL and RPMForge repositories configured.

# yum repolist | grep "epel|rpmforge"
epel Extra Packages for Enterprise Linux 6 - x86_64          7,571
rpmforge RHEL 6 - RPMforge.net - dag                         4,390

Now, as root, I'€™ll install the Ansible RPM.

# yum localinstall ~/ansible/rpm-build/noarch/ansible*.rpm
Installed:
 ansible.noarch 0:0.5-1.el6                                                                                      
Dependency Installed:
 python-babel.noarch 0:0.9.4-5.1.el6  python-crypto.x86_64 0:2.0.1-22.el6                     
 python-jinja2.x86_64 0:2.2.1-1.el6.rf python-paramiko.noarch 0:1.7.5-2.1.el6                  
 python-yaml.x86_64 0:3.09-3.el6.rf                     
Complete!

And now we have the ansible command available, and it'€™s installed via RPM:

# which ansible
/usr/bin/ansible
# rpm -qf `which ansible`
ansible-0.5-1.el6.noarch

Using Ansible

Connectivity Test

Let'€™s do a quick test to make sure our install of Ansible is working AND that my user can login to whatever servers are in the ansible_hosts file.

$ env | grep ANSIBLE_HOSTS
ANSIBLE_HOSTS=/home/curtis/ansible_hosts
$ cat ~/ansible_hosts
127.0.0.1
$ ansible all -m ping
127.0.0.1 | success >> {
   "ping": "pong"
}
$ ansible all -a "hostname"
127.0.0.1 | success | rc=0 >>
buildbox

Looks good. We are set to go!

Ansible Playbooks

Most configuration management systems support some kind of '€œencapsulation'€ to actually repeatedly configure systems.

For example, Chef has cookbooks.

Cookbooks are the fundamental units of distribution in Chef. They encapsulate all the resources you need to automate your infrastructure and are easily sharable with other Chef users. – http://wiki.opscode.com/display/chef/Cookbooks

Puppet calls theirs Modules. Ansible uses another term: Playbooks.

Installing Apache Virtual Computing Lab with Ansible

At Cybera we are using Apache VCL on a few projects. I'€™d like to get VCL setup on a single node using Ansible so that I can easily create VCL head nodes for testing purposes.

Connectivity Test

The first thing I'€™m going to do is make sure that I have a VCL group configured with the name or IP address of the target virtual machine (which in this example is 192.168.122.11).

$ cat ~/ansible_hosts
[vcl]
192.168.122.11
$ ansible vcl -m ping
192.168.122.11 | success >> {
   "ping": "pong"
}

How did my local user '€œcurtis'€ know to login as '€œroot'€? Because I have it configured in my ~/.ssh/config file:

$ cat ~/.ssh/config
Host vcl-test
HostName 192.168.122.11
User root

Now we can run the setup process, which will ensure all the correct software is installed and running.

Checkout the VCL Ansible Playbook

On the machine you intend to run Ansible and Ansible-Playbook on, check out the Cybera VCL Playbook.

$ git clone https://github.com/cybera/ansible_playbooks.git
SNIP!
$ cd ansible_playbooks/vcl

Configure main.yml

There are several variables to set up before we can run Ansible-Playbook. Copy the vars/example_main.yml to vars/main.yml.

$ cp vars/example_main.yml vars/main.yml

Then edit the main.yml file and set all the appropriate variables.

Run setup.yml

First we want to setup the VCL server instance with all the required code and dependencies, make sure the web server and database server are running, and also create the secrets.php and conf.php files.

$ ansible-playbook vcl/setup.yml
SNIP!
PLAY RECAP *********************
192.168.122.11       : ok=  18 changed=  11 unreachable=   0 failed=   0

The setup group of tasks can be run many times.

Run init.yml

The init command should only be run once, the first time the system is installed. Running it more than once will fail because the database has already been set up.

$ ansible-playbook vcl/init.yml
SNIP!
PLAY RECAP *********************
192.168.122.11      : ok=   9 changed=   7 unreachable=   0 failed=   0

Connect to VCL

At this point you should be able to connect to https://hostname.domain/vcl/ (note the /vcl, which is hardcoded right now in the playbook) where host name and domain are the variables that were set in the main.yml file, and login with the default user name and password.

Conclusion

I think it took about six total hours to get going with Ansible, and deploy a fairly complicated system such as Apache VCL. VCL is a good example because it uses a database, runs some shell scripts to configure itself, and has a couple of configuration files.

The things I got stuck on were the fact that I didn'€™t realize that once a particular task had failed, Ansible didn'€™t continue running the rest of the tasks. That cost me some time.

I also had run with debugging on, but didn'€™t realize that means events are logged into the remote clients'€™ machine'€™s syslog file, /etc/syslog/message, and not standard error where Ansible or Ansible-Playbook is being run.

Finally, I wasn'€™t clear when the handlers were run. Once the vcl.conf file is copied over, Apache needs to be restarted. There is a handler for that, but when is it run? It took me a while to realize that I need to specifically notify the handler after an action.

That said, I am quite happy with Ansible and it will be my go-to configuration management system in situations that don'€™t call for the extra complexity of Chef or Puppet. I also love that it uses SSH instead of its own in-house PKI management system.