Use your favorite language with the multi-node software deployment platform.

If you know me, or even better — if you work with me, you know I’m a huge fan of immutable infrastructure, continuous deployment and delivery, and automation scripts. I write a lot of bash or Ruby code that makes things for me. I leverage command line rather than UI tools and I extensively use rake tasks whenever I have an opportunity.

My usual tech stack is as follows:

Capistrano / Mina —

project deployment

project deployment CircleCI / CodeShip —continuous integration

Ansible / Chef —

infrastructure automation

History

I’ve been using Chef for a while so far and I like it in general. However, sometimes I find it overwhelming for simple use cases, which I deal with most often. A couple months ago I came across Ansible and from the very beginning, I knew that it was the perfect tool for my needs.

Ansible

Ansible is an IT automation tool. It can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates.

Basic features:

Ansible manages machines in an agentless manner.

Ansible is appropriate for managing small setups with a handful of instances as well as enterprise environments with many thousands.

Ansible is decentralized — it relies on your existing OS credentials to control access to remote machines

Ansible is based on a push model by default, like chef-solo and opposite to chef server, but can be configured to work as a pull model as well

By default, Ansible will try to use native OpenSSH for remote communication when possible and in case of any problems it will fallback into Python implementation of OpenSSH called ‘paramiko’

Ansible playbooks are expressed in YAML syntax

Ansible, Inc. releases a new version of Ansible approximately every 2 months

Modules

The most basic and important components of Ansible are modules (called the ‘module library’) that may be executed directly on remote hosts or through Playbooks. Modules let us control system resources, like services, packages, or files (anything really), or handle executing system commands.

Ansible is written in Python and so are these modules, however it doesn’t stop you from using various languages to create them. You do not have to write modules in any particular language.

The only requirements for modules are:

All modules have to return JSON format data

format data Modules should be idempotent, meaning they will seek to avoid changes to the system unless a change needs to be made

Ruby

When I was migrating from Chef, I was afraid of not using Ruby anymore. I wondered what would happen if I want to create some custom task, not available in Ansible core modules. Fortunately, after reading the Ansible documentation, I found that I can still use Ruby for my specific cases.

Ansible offers a module called stat, which retrieves facts for a file similar to the linux/unix stat command. However it doesn’t provide all the properties I’d like to check — that’s why I’ve decided to write my own module.

Based on the aforementioned requirements I ended up with the following code:

Now we’d like to use it to check i.e. for Ruby executable:

- name: Retrieve status of Ruby executable

stat: dir_path=/usr/bin/ruby

register: status_of_ruby_executable — debug: msg={{ status_of_ruby_executable }}

Summary

It is awesome that these days we have a lot of tools to increase our productivity. We improve and automate our workflow solely by using these tools to tackle any tasks we come across. I highly recommend you to take a look at Ansible, because it will help you create immutable infrastructure with reusable components that can be applied for many remote machines. And you still stick up with Ruby!

If you want to be notified about recent posts from my blog:

https://tinyletter.com/KamilLelonek

Resources

Complete example is available on my GitHub