Ansible coming from a Fabric perspective

Hi, I’m new to Ansible and I’m evaluating it to see if it’ll be a good replacement for my current Fabric/Fabtools-based deployment tool.

My application is fairly simple, just a simple LAMP stack, and therefore my current deployment tool is also not too complicated. I can deploy service configurations, install system and python packages, upload my application code and restart servers in under a minute. And all this organized in a single fabfile.py file that I run like fab staging deploy.

However, reading over the intro docs for Ansible, I’m a little overwhelmed by the immense complexity of the system compared to what I’m currently using.

For example, in my toolkit, to ping a server I would run:

fab role ping

but from one of the first examples in the Ansible intro docs, it would be:

ansible all --inventory-file=inventory.ini --module-name ping -u username --private-key=~/path/to/private_key

Are all the commands that long or is there some way to more compactly represent them like in Fabric?

The other aspect of Ansible that makes me nervous is its slow performance. This often cited blog post (http://ryandlane.com/blog/2014/08/04/moving-away-from-puppet-saltstack-or-ansible/) mentions that for a “no change run”, where Ansible literally has to make no changes, it takes 2 minutes to complete. My current tool can do a full code deployment in 30 seconds, so I’m perplexed why Ansible would take that long. I think Ansible might be scanning every file previously deployed and checking it for changes, something my tool doesn’t need to do. Is it possible to disable this feature and make Ansible only push changes without constantly re-checking the server?

What attracted me to Ansible was the fact it’s written in Python, its agent-less SSH-only design and large community. However, it seems to suffer the same problems as Chef and Puppet in that it feels overly complicated for small projects. Am I off base? Should I invest in Ansible, or would it be better to stick to Fabric/Fabtools for a small project?

Hi,

For example, in my toolkit, to ping a server I would run:

fab role ping

but from one of the first examples in the Ansible intro docs, it would be:

ansible all --inventory-file=inventory.ini --module-name ping -u username --private-key=~/path/to/private_key

You should have a look for the ansible.cfg configuration. If you put one into your project directory you can define the ansible_user, inventory and key file for this user and do not need to specify them on the command line. I think the “all” group is default, no need to issue.

This would result in:
ansible -m ping

I’m relatively new to ansible, haven’t had performance problems so far. I think you can speedup things by configuring ansible to run in parallel or break your hosts down into smaller groups. ansible will “compile” a python script from your playbooks, transfers and runs it on the destination servers. This takes some time, I guess.

Regards,
Marcus

Some of the 'performance issues' that people report with ansible is
comparing it to 'agents' which don't need to ssh into the boxes, copy
the code and run tasks.

Thanks, that’s interesting. I was hoping I’d overlooked something.

I’m mainly looking at Ansible because I want a simpler tool to speed up my deployments. I currently manage a multi-tenent multi-server application, so my “full deployment” looks like:

  • install system packages
  • install custom service configurations (Apache/Postgres/MySQL/RabbitMQ/etc)
  • install pip packages
  • upload custom static media
  • install custom application code
  • initialize N databases
  • apply Django/South migrations for N databases
  • restart/reload services

Obviously, most of these tasks don’t need to be done for every deployment. They only need to be done once initially, and then again when an underlying resource changes in my code repo. To run this full process takes about 45 minutes, so instead I’ll manually run subsets of this process. This is much faster, but it can be hacky and prone to error if I overlook something (e.g. I updated my pip requirements but forgot to install the new package).

I’m hoping to find a configuration management tool with a form of idempotency that will achieve this by keeping a local ledger of differences between production and the repo. Unfortunately, I can’t find anything in the Ansible docs that suggests it can work this way, meaning Ansible would have to run every step of the process.

I find it really difficult to believe that no one else finds the concept of a local ledger useful. I’ve gotten into heated debates with Puppet/Chef fans for even suggesting the idea, and they fervently claim that checking every server’s entire configuration for every deployment is the only acceptable implementation of idempotency in a CM tool. They don’t care about tasks that take minutes to run even if no changes need to be made. For example, I use several dozen Django applications in my project, so running “manage.py migrate” can take about 15 minutes to run even if no migrations are pending because it checks every application across every database.

Is this a problem anyone else has had to deal with? What’s the usual solution in Ansible?

Have you considered setting local facts. You could then test for the local fact being present and then skip steps which don't need to be repeated?

ansible does not keep state, that does not mean you cannot. You can
use local facts as mentioned above or you can use callback/lookup
plugins to keep your own data store up to date. I would also ping the
Ansible Tower team as they are working on things in this direction.

Hi,

What about using tags and sorting out those tasks you need for an deployment? Running just half of your playbook?

http://docs.ansible.com/playbooks_tags.html

Regards,
Marcus

Actually, I prefer to have separate playbooks for configuration
management and deployment. The 1st rarely involves orchestrating
servers in anything complicated where ordering matters. And the 2nd
almost always involves ordered steps across multiple servers. That way
things can deployed without having to do a CM run for all the
machines.

It's nice the ansible does both configuration management and server
orchestration (application deployment), but that doesn't mean it
should all be in the same playbooks.