See all blog posts

Why I love and hate Ansible

Full disclosure: I’m a casual user of Ansible, Python and Bash. I’m not an expert on any of them. The notes below are my personal impression after playing around with Ansible for a few months, mostly to run ScyllaDB and Cassandra clusters on EC2.

Why I love Ansible:

Ansible is straightforward to use, no batteries (or local agent) required. When I have a herd of ScyllaDB servers, I can stop the service on all of them just by running

ansible -i my.ini ScyllaDB -u centos --sudo -m service -a "name=scylla-server state=stopped"

Ansible is declarative, you state the end state, not the actions.

More examples:

Want to update a row in scylla.yaml? Use the lineinfile module.

ansible -i my.ini ScyllaDB -u centos --sudo -m lineinfile -a 'dest=/etc/scylla/scylla.yaml regexp="auto_bootstrap: false" line="# auto_bootstrap: false"'

Use nodetool to refresh tables.

ansible -i my.ini ScyllaDB -u centos  -m shell -a 'nodetool refresh
keyspace1 standard1'

Even better, when running on Amazon EC2, I can use EC2 dynamic inventory to allow me to do the same without even managing my local server list (my.ini above).

Organized
Next natural step is to group tasks into to playbooks, and then organized them into roles. Each role is responsible for a task such as installing Java or installing ScyllaDB. For example, in my ScyllaDB/Cassandra project, I created roles for Cassandra and ScyllaDB configuration. Roles are to Ansible what functions are in a programming language—building blocks to combine.

Automation in action
Automation, with no batteries required

Big ecosystem of module and extensions. I already mentioned the EC2 module, and I use the service and lineinfile modules above. There are many more, to do anything from removing and adding packages, to manipulate directories, to what not.

What I hate (really just dislike) about Ansible

Let’s say I want to remove a directory as part of a playbook. Easy, I will use the file module:

- file: path=/data state=absent

Missing a module? Just write your own in python What’s not to like? Well, I already have a way to remove directories in Unix, rmdir, and a way to remove directories in Python, os.rmdir. Ansible introduce a new layer of abstraction one need to learn for every single command, from ls, to mkdir to yum. Here are two more examples:

Set operations and varibales

As part of my stress playbook I extracted IP addresses of servers in the intersection of groups DB and aRegion. Again, the Ansible solution is pretty slick:

    - debug: msg=""
      with_items: groups.DB | intersect (groups.aRegion)
      register: output

The intersect command comes from Jinja2 filter, one more DSL to learn when using Ansible, and register is the way to store values in variables.

Loops

Ansible has loops and even nested loops. Here is a simplified example from the same project, waiting for all servers to open SSH port:

    - name: Wait for SSH to come up
      wait_for: host= port=22 delay=60 timeout=320 state=started
      with_subelements:
        - ec2_load.results
        - instances

In all of these examples, and there are more, Ansible provide a reasonable solution which is very different from what Python or Bash provides. On some cases better, on other, like flow control, worse.

Can we do better?

It is very common for a DSL to be so useful, that people will stretch it beyond its original goals (ant, XSD, many more). Is it possible to have the Ansible functionality as a Python internal DSL? Can we use Python control flow, while keeping the high level, declarative abstraction of Ansible? Someone smarter than me will need to answer these questions. In the meantime I will keep using Ansible. Now that I’m ⅔ up the learning curve, I’m too afraid to climb down.

Subscribe to this blog’s RSS feed for automatic info. Or follow ScyllaDB on Twitter.

Photo by RamaOwn work, CC BY-SA 2.0 fr, https://commons.wikimedia.org/w/index.php?curid=481562

About Tzach Livyatan

Tzach Livyatan has a B.A. and MSc in Computer Science (Technion, Summa Cum Laude), and has had a 15 year career in development, system engineering and product management. In the past he worked in the Telecom domain, focusing on carrier grade systems, signalling, policy and charging applications.