As pretty much any web development company, we do quite a bit of web hosting as well.  And web hosting tends to grow infrastructure – networks, firewalls, routers, servers, storage, access control, monitoring – these are just some of the things that need constant attention.  There are, of course, tools and technologies that help with all that, and we are using them extensively.

Puppet is one of such tools.  It is a configuration management solution that helps to simplify and automate configurations.  We’ve been using Puppet for the last year and a half, and think that it’s great.  But there is another tool in the same domain – Ansible – which we think suits us better.  In the last few weeks were were experimenting with Ansible – trying things out, comparing it to our current Puppet setups, and looking into things we could do better.

We liked Ansible so much that we’ve decided to migrate from Puppet.  Here are a few reasons for us to do so.

Simplicity.  Ansible is a much simpler tool.  Puppet manifests are written in its own domain-specific language (DSL), which is a subset of Ruby.  Ansible uses YAML for its playbooks.  Both are simple, but YAML is simpler.  It’s also much easier to both parse and generate programmatically.  After experimenting and comparing the two for a bit, we were surprised to discover that it is in fact easier to create large, complex setups using a simpler language.  With Ansible, there’s often one true way to do something.  As limiting as it sounds, this also makes for much more readable and maintainable configurations.  There are no different coding styles, or approaches, or philosophies. This forces one to have smaller bricks when building larger walls.

Push vs. pull. This is probably the greatest difference between the two.  Puppet uses the pull model.  It is setup either in master-slave configuration, where the puppet master server keeps on configurations, and controlled machines periodically check with it, if there’s something new for them to reconfigure; or, using a master-less setup, all configurations are kept in repository somewhere and each machine pulls the repository periodically and runs the configuration update, if needed.  While both approaches work well, they add an extra bit of complexity when provisioning the servers – machines need access to the repository, or a master server needs to be running.  Ansible uses push approach instead, where a playbook is usually executed from the single controller machine, which then connects to all the necessary remote machines (usually via secure shell (ssh)) and performs all the necessary checks and configurations.  This approach just suits our scenarios much better.

Modules.  Both Puppet and Ansible have a whole lot of modules that simplify configuration and deployment of many popular applications – from web servers like Apache and Nginx, databases like MySQL and PostgreSQL, to cloud infrastructure on Amazon AWS and Microsoft Azure.  With Puppet however, most modules have to be separately installed – often blowing up the size of the repository used for the configuration.  Ansible, on the other hand, comes with a lot of modules built-in.  Additional modules can be easily installed too, but we didn’t have a need to touch those yet.  Which makes the configuration repository small and playbooks very portable.

We are still in process of converting our Puppet manifests and modules to Ansible, but even with the work that we’ve completed already, the size of the repository decreased significantly. We are also much more comfortable with the new layout and syntax, which means there will be more enthusiasm in pushing more of the configuration and deployment work for our infrastructure to Ansible.  And more automation usually means faster delivery, more consistency, fewer human errors, and easier troubleshooting – all of which are the good things we here at Qobo strive to achieve.