Provisioning and deploying applications has become an important aspect of building scalable applications and delivering features continuously.

Ansible, a relatively new tool for application deployment and configuration management has become a very useful tool to incorporate in any project which requires any level of automation on the deployment of its components.

Why Ansible?

Automating with Ansible literally just means writing a bunch of YAML files declaring what the state of the different hosts should be, trying to do so regardless of what their actual state is. This declarative sort of specification done in a static format (YAML) is what makes Ansible a very easy to use option compared to its competitors (Puppet, Chef, etc).

Unlike these other automation tools, Ansible does not require a client (or agent) installed on the hosts, which makes it even easier to get everything up and running.

Nuts and Bolts

The state of the different hosts listed on an inventory is declared through a playbook, which contains a few roles, which contain a series of tasks. These is what each of these elements are meant to be used for:

  • task - this is the most atomic element, it is a single declaration that specifies part of the state in which the host should be. E.g. “the libxml package has to be present”, “the project repo has to be in directory X with version master”, etc.
  • roles - these encapsulate a set of tasks that have a common, coupled behavior. They also contain the configuration and template files needed for any of the role tasks, specific variables available to this role and handlers which are triggered whenever a certain condition is given. An example of a role would be “sqlserver”, which would install a postgresql database and configure the database and its users.
  • playbooks - these specify the hosts and roles, they are the starting point (where the execution begins). These can also specify variables and standalone tasks.
  • inventories - these specify the hosts and groups for which they could be classified. For example, you could have an inventory named “production”, which lists the production hosts and groups them into “apiservers” and “clientservers”.

Given a playbook and an inventory, you would now be able to run it. If I wanted to provision production with the provision-api.yml playbook, I would simply run:

$ ansible-playbook -i production provision-api.yml

This provision.yml playbook, could contain the following:

---
- hosts: apiservers
  vars:
    db_user: my-api
    db_pass: my-pass
  roles:
    - common
    - dbserver

While the production inventory would contain:

[apiservers]
api.mysite.com
api-2.mysite.com

[clientservers]
mysite.com
static.mysite.com

Ansible also provides multiple other directives to allow more complex tasks to be done easily. I would recommend you to check the documentation for a better insight into what can be done with it.

Conclusion

When it comes to tools for automating your entire setup for a given project, Ansible is most likely to be the best choice. The lack of configuration needed to get it up and running and its ease of use make the task of managing components a lot easier, to the point where it is enjoyable, even for newcomers. I would suggest you to at least try it out for a project to fully understand its advantages.

I’ve made a skeleton project containing multiple example roles. You could use this as an example of a classic ruby web application which uses a SQL database and webpack assets compilation.

Hope it helps!