The other day I quit working with one of my Chef repositories for some servers I manage. I quit in rage. I quit because nothing worked how I wanted it to.
I started using Chef in 2011. At that time, Puppet and Chef were the big players in this space. I had no need or interest in setting up a central server, just a need to manage some configuration. I was very familiar with Ruby and Python, but used Ruby day to day. Using Chef with Spatula and then Knife-Solo became my approach to managing servers. Ansible wouldn't be released for another few months.
Chef was great. It is still great. Ruby is awesome to work with and Chef performs extremely well in many situations. I've done some really great deployments with Chef, and I will continue to use those setups.
My problem with Chef almost always comes down to needing to update or add something. Updating a cookbook can have a huge ripple effect on my setup due to cookbook dependencies. Adding a new cookbook for a new component can cause the same dependency pain.
Updating the Chef client itself can cause a huge chain of headache. Even just moving the operating system version can be super painful because it will result in the need to update many cookbooks, and then a chain of dependency updates.
Fundamentally, my usage of Chef doesn't align with Chef's goals. Since I'm not using a Chef server, my repository of truth is the git repo that I store my Berkshelf file, node files, and custom cookbooks. I only ever run chef in a
push mode where I send the cookbooks to the server and instruct it to run them. This is not what Chef is optimized for.
Time to change course
In my frustration, I decided to seek out other options.
With Puppet, I felt like I'd be in the same boat I was in with Chef. I was not a fan of SaltStack's marketing website, and while I've heard good things, I just couldn't see the benefit in my quick research.
Ansible won me over with a few key points.
Here are the points that really sold me on giving Ansible a shot:
- Agentless architecture - I don't need to install any kind of agent to connect to a central server, or get used in a what beyond what it was intended.
- Execution order - The tasks that run do so in a very predictable way.
- SSH Based Approach - The entire approach of running a chain of basic commands via SSH really spoke to me. I've done similar things with Ruby's SSHKit.
- Designed to work with version control - The configuration of Ansible lends itself to be version controlled in Git like the rest of my stuff.
- Designed for ad hoc parallel task execution - This fits my needs really well.
So much YAML. With Ansible, configuration is described through playbooks, which are written in YAML. It takes a bit to get used to the approach. Once you get the approach, the basic building blocks don't take that long to learn, and you can do a lot with them.
It can feel very strange to represent basic commands as YAML, but it does work, and it gives a lot of flexibility. It can be frustrating that there is usually more than one way to represent the same command. Additionally, to make a really flexible set of playbooks to meet various needs does take a deeper understanding of how Ansible works and decides what to include and run.
The output is very clear, and can be made very verbose to give you a great understanding of what is happening on the server.
When compared to Chef, there just seems to be less magic than other things I've tried. That is what I was looking for. I need it to do a simple job, and do it well, not be full of magic.
I feel like a lot of my problems with Chef stem from getting cookbooks from the supermarket, and then pulling in a ton of dependencies, which then eventually conflict with each other. This problem seems to be very less relevant with Ansible's Galaxy of playbooks.
The issue that there does seem to be with Ansible Galaxy is just a ton of playbooks to do the exact same thing. This is perhaps because they are very simple, and you can easily make your own, or find the one that behaves just how you want. The downside is that you can't just go to the galaxy and search and expect to find the one playbook to solve all your problems, at least not without digging. That digging though, does require that you can look at the playbook source and know what's going on. This was frustrating as a new user, but looking at all that YAML did really help me understand more about Ansible and how it works.
I'm really happy having learned some Ansible, and I'm eager to use it in more scenarios. It seems to fit my needs without bringing far more to the table than I need. It is simple and powerful and does what I want. I'll call that a win most days.