Ansible Playbooks – A more advanced example

Nov 26, 2014 • Jonathan Frappier

In my last post, I showed you a simple example of an Ansible playbook using yum to update a package. Still really awesome, especially when you consider how often you might need to do that and how simple it is to handle that type of otherwise manual task. In this post, I am going to try and put together a slightly more complicated playbook to look at some of the other options available.

Please note I am not necessarily trying to reflect best practice here, but rather demonstrate some of the different options available in an Ansible playbook. There is likely an easier way to do this for production purposes

So what else can we do? Let’s start at the top. First and foremost you are probably not going to log into your systems as root, typically you log in with a user account and then use “sudo” to elevate your privileges. I have created an account on my “db” server called virtxpert, and added that user to the sudoers file. Now I can do something like this in my playbook:

Since, as I mentioned in the last post playbooks take an idempotent stance, I can run that playbook again with the remote user being virtxpert and see no changes, because my single task was already complete. With sudo a requirement now I also need to add –ask-sudo-pass to the command.

As you can see here, everything “worked” as expected - there were no changes that needed to be made. Now instead of just updating a package, lets install something generally a bit more complicated - PostgreSQL. I could just do yum: pkg=postgresql state=;latest and in CentOS6.4 that would be Postgres 8.4 - but what if I want 9.x? My playbook would look something like:

Wow, just wow - a few lines of Ansible and PostgreSQL 9.3 is installed.

You can also see it here on the database server itself

But after the installation, the PostgreSQL service is set to off and is not started. We also have initialized PostgreSQL yet. We could possibly use the args service option,but lets try the shell tasks to run service postgresql-9.3 initdb!

- name: initialize postgresql
shell: service postgresql-9.3 initdb

Wow - how easy is that! Now in the grand scheme of things, this might not be the best way to initialze PostgreSQL, after all we are just telling Ansible to run this command, it has no way to know whether it has been run before or not but I wanted to illustrate using this option.

Now, how could I do make sure that PostgreSQL starts with the server and starts up after the playbook is run? Well now we can use what is called a handler for this. For example we might want something like:

And just like that - PostgreSQL is now started - here is chkconfig –list and ps -ef | grep postgresql-9.3 from the DB server the playbook was run on. You can see that postgresql-9.3 is now set to on since we set enabled=yes and started since we set state=started

That’s it for now on Ansible, next I think I want to look at the Ansible and VMware integration - stay tuned!

With Ansible installed, and a basic inventory file created we can now move beyond ad-hoc tasks (which by the way is still a great use case for Ansible) and take advantage of Playbooks. Playbooks are a set of commands organized as required to perform complicated tasks. Maybe you have provisioned dozens or hundreds of new virtual machines and you now need to make sure they are in the desired state - standardized versions of OpenSSL or MySQL for example, then deploy your custom software packages to those servers; that (simplistically) is where playbooks come in.

Now that CentOS7 is out, time to make sure I can setup my virtual machines with the VMXNET3 vmnic. As I documented in my previous post, CentOS 6.x using the VMXNET3 driver requires VMware Tools, VMware Tools needs Perl, Perl is not included in the minimal ISO so I need network access to get Perl to install VMware Tools to get network access. That order of operations doesn’t work very well.