Using Ansible Galaxy

2020 Update: This article is still as relevant as ever, though Galaxy now has tens of thousands of roles and also has 'Collections' now, which can include plugins, modules, and roles! If you want to learn the latest about all this stuff, check out my fully updated Ansible for DevOps, now in it's 2nd edition! It has two chapters covering roles and collections on Ansible Galaxy.

Ansible Galaxy Logo

Ansible Galaxy was launched just a few short months ago, and already has over 500 roles maintained by over 225 users. The idea behind Galaxy is to give greater visibility to one of Ansible's most exciting features: reusable Roles for server configuration or application installation.

Galaxy is still in beta, and likely will be for a while longer, but if you have Ansible 1.4.2 or later installed, you can use the ansible-galaxy command to get started.

You may not know the power of Ansible Galaxy (or, indeed, Ansible Roles, which have been around since 1.2, and were greatly improved in 1.3+) until you've had a little taste of what it has to offer. In this post, I'd like to highlight how to get started using ansible-galaxy in particular, and how you can put together fully-featured servers with roles like lego blocks, and very few lines of YAML.

The topic of this post is greatly expanded in Ansible for DevOps, a book I wrote on Ansible.

Getting roles from Galaxy

One of the primary functions of the ansible-galaxy command is retrieving roles from the Galaxy. Roles must be downloaded before they can be used in playbooks[1].

I'd like to build a quick LAMP server to test some newfangled PHP script I wrote with one big 800 line function. So, I'll just do the following:

$ ansible-galaxy install geerlingguy.apache geerlingguy.mysql geerlingguy.php

The latest version will be downloaded if no version is specified. To specify a version, add the version after the role name[2]:

$ ansible-galaxy install geerlingguy.apache,1.0.0 geerlingguy.mysql,1.0.0 geerlingguy.php,1.0.0

A LAMP server in seven lines of YAML

Now that we have these roles installed (Apache, MySQL, and PHP), we can quickly create a LAMP server. This example assumes you already have a CentOS-based linux VM or server booted and can connect to it or run Ansible as a provisioner via Vagrant on it:

1. Create an Ansible playbook named lamp.yml with the following contents:

---
- hosts: all
  roles:
  - geerlingguy.mysql
  - geerlingguy.apache
  - geerlingguy.php
  - geerlingguy.php-mysql

2. Run the playbook against a host:

$ ansible-playbook -i path/to/custom-inventory lamp.yml

Boom. LAMP server.

A Solr server in six lines of YAML

Let's grab a few more roles so we can build a Solr search server.

$ ansible-galaxy install geerlingguy.java geerlingguy.tomcat6 geerlingguy.solr

Then create a playbook named solr.yml with the following contents:

---
- hosts: all
  roles:
    - geerlingguy.java
    - geerlingguy.tomcat6
    - geerlingguy.solr

Boom. Solr server.

I think you might get the point. Now, I could've easily left out the java and tomcat6 roles, since they'll be automatically picked up during installation of the geerlingguy.solr role. Additionally, each of these roles has a good deal of customizability in the form of variables. And obviously, you'll need to do more configuration (like securing the server, setting up user accounts, etc.), but I'm even working on flexible roles for that, too, like my firewall role for any Linux OS using iptables.

The roles' pages on the Ansible Galaxy website highlight the available variables for setting things like what version of Solr to install, where to install it, etc. (for example: geerlingguy.solr Galaxy page).

I've been abstracting all my playbooks for the infrastructure I manage into distinct application-related roles, and doing so has allowed me to have a set of around 30 roles (most of which have been uploaded to Galaxy: geerlingguy's roles on Ansible Galaxy) I can use to build a very wide variety of servers. Instead of having to maintain lengthy playbooks unique to each server, I can just build a list of the required roles, and a few variables that set up the servers with the proper versions and paths. Each server is defined in a few simple lines of YAML.

As I said... Boom!

Other Helpful Galaxy commands

Some other helpful ansible-galaxy commands you might use from time to time:

  • ansible-galaxy list displays a list of installed roles, with version numbers
  • ansible-galaxy remove [role] removes an installed role
  • ansible-galaxy info (hmm... not sure what this does?)
  • ansible-galaxy init can be used to create a role template suitable for submission to Ansible Galaxy

Additionally, you can configure the default path where Ansible roles will be downloaded by editing your ansible.cfg configuration file (normally located in /etc/ansible/ansible.cfg), and setting a roles_path in the [defaults] section.

Room for improvements

Even with all the great utility Ansible Galaxy provides, there are a few things I think could be improved:

  1. For contributors, some parts of the process aren't immediately obvious, like whether roles on Galaxy will automatically refresh (and if so, how often) when changes are pushed to GitHub.
  2. When searching for roles, it's currently impossible to filter results by distro or OS version; if you have a CentOS server, and most of the results are for Ubuntu, it can make the process of finding a role to use difficult.
  3. The ansible-galaxy command's documentation isn't incredibly obvious or clear, but it's been improving :)
  4. There is currently no way to simply update a role (to my knowledge); you'd have to remove the role then download a new copy with the proper version.

All of these complaints are borderline trivial, and since Galaxy is still in beta status, I expect they'll be worked out in due time (indeed, I hope to help with the process!).

All in all, I'm very impressed with Ansible Galaxy as it exists today, and I hope you can start using it to accelerate your infrastructure development! If nothing else, spinning up quick servers to try out new apps or other packages listed in Galaxy can be an enlightening process.

If you'd like to learn how Ansible can help you manage your infrastructure, and are either new to Ansible or already using Ansible, you can purchase my book, Ansible for DevOps, on LeanPub, Amazon, or iTunes.

[1] Note that, as of this writing, downloading a single role will not necessarily download all its dependencies (though a --no-deps option seems to imply this would be the expected behavior). Nor will running a playbook referencing an external role automatically download the role. You will need to run ansible-galaxy install for each role you need.

[2] There's no way (at least not that I know of) to get the master/HEAD release from GitHub after a version has been tagged. I tried master, HEAD, and head, but those resulted in errors. It would be awesome if we could specify head, or even a specific commit, when downloading roles. Versions cover more than 99% of use-cases, though, so I'm not going to complain loudly :)

Comments

I came here looking for "how the heck do I update my roles?" only to see it's still up in the air.

Instead of removing manually, I ran `ansible-galaxy -r requirements.yml -f` it force installed newer versions.

Jeff,

Thank you for the guide and the multitude of roles you have shared.

I am just learning about Ansible.

I cloned the repositories for you PHP, MySQL, and Apache roles.

I don't see anywhere that you install the php-mysql package. I understand that this kind of cuts across the two concerns of the roles, so how is that handled? I saw that you have a php-mysql role, but in this article you did not use or reference it.

Can you clarify that for me?

You're correct; you also need the geerlingguy.php-mysql role; I've updated the article too.