I’ve gone through quite a few configuration management tools and have come away with a few lessons learned. I often see posts asking about configuration tools and I thought I’d write a quick outline since there aren’t enough blog posts on configuration management already /s. I’m only going to focus on the big 4 in this space; Ansible, Chef, Puppet, and Salt. Chef is the one I’ve least used, so if anyone has any corrections please let me know.
Configuration Management Architecture
I like to think of these tools as having 3 separate categories of architecture.
- Agent based pull
- Agent based push
- Non-Agent SSH based
Agent based pull
Puppet and Chef fall under this. Chef and Puppet install an agent daemon on the hosts to be managed. This daemon is configured to run at specific intervals. There are ways to push to each of these as well but that’s not how they were designed or meant to be used. There’s also masterless mode (at least on Puppet).
Agent based push
I wasn’t quite positive how to classify Salt. It’s actually a command executor on a message bus. It is typically ran from the master server with a salt command (state.apply if you have salt/pillar configured with a top.sls file). It’s a bit more flexible than the others because it’s just a command executor on a message bus. It can run masterless as well and comes with a variety of other tools like salt-cloud.
Non-Agent SSH based
For anyone that’s used Ansible, this was obviously Ansible. Ansible connects through SSH and needs no agent. You do have to have a valid login and privileges to perform the commands in your playbook.
CM Market Share
This chart is a little old but I feel like I should include info about market share. As you can see, Puppet and Chef make up most of the market share with Ansible seriously gaining ground lately.
What I like and don’t like about each
Each of these systems has attributes I don’t really like and some that I do. My biggest preference is that configuration management is at least used and in version control.
I prefer an agent on persistent machines, I prefer no agent for provisioning or running remote commands quickly. I also prefer the 2 built in python (Ansible, Salt) because I prefer python over ruby. I use Ansible the most, but that’s because frequently use it to run Jenkins jobs or provision machine images.
Puppet was the first configuration management system I used and I spent a good few years using it. I like that Puppet maintains state and will pull from the master in set intervals. I think Puppet can make a great tool for persistent systems that won’t have code pushed to them. ElasticSearch clusters, mongodb clusters, graylog clusters all great with Puppet. Puppet worked fine when configuring services on servers and deploying things from rpms.
Puppet’s shortfalls are that it isn’t great at remote command execution. States aren’t in specific order unless anchored or dependencies are added to the code. It wasn’t the right tool for pushing code to servers. Be ready to build rpm/deb packages (good thing there’s fpm) to really feel like you’re using it correctly. If you have a good pipeline to sync and build yum/dpkg repos and host them with the proper security (https, gpg signed packages, etc) this can work fantastically but it’s a lot of up front work getting repos put together. Puppet also runs everything on the Puppet-Master server, which is fine for smaller environments (I had no problem with 350+ nodes polling at 30 minute intervals). There are some amazing engineering feats out there to scale out Puppet, I’m happy I never had to tackle that problem.
Ansible is FANTASTIC for smaller environments. If you’re managing < 100 servers you should definitely check out Ansible. If you have < 20 servers I probably wouldn't use anything else. I do REALLY like Ansible but it takes a lot of discipline to use Ansible well in large environments and I find it best used for provisioning or remote command execution alongside puppet/chef. Like I said, I REALLY like Ansible... I just like it as a packer provisioner or in a Jenkins job more than anything else. Ansible isn't great at maintaining state because there's no agent. If you have the discipline to never SSH or never allow anyone to SSH into the server than you can do alright with Ansible. Bigger environments seem to get messier quicker with Ansible than with anything else I've used. Ansible's ability to pull like Chef and Puppet seems like more of a work around than the other tools different functionality. Ansible seems to get a lot of support online but I think that's because it's the lowest barrier of entry into config management tools. That's not me talking bad about it, it's just that it's easier to use, setup, and understand than any of the other tools.
Salt seems like it can do everything. It has a ton of functionality and flexibility because it’s just a command executor running from a message bus. I think it’s ZeroMQ under the hood. I quickly took to pillar and once again the word flexibility crosses my mind. I like the way you can draw out dependencies in Salt best. The watch attribute is better than writing and using handlers (Ansible) or setting up dependencies or anchor dependencies (Puppet). Salt is also probably he fastest out of all of them and the easiest to scale.
Salt has the worst documentation but I think that’s because there’s just SO MUCH STUFF. There’s a module or command for pretty much everything and the issue is that nobody maintains some of them or writes up good documentation on everything. There’s a lot of development on Salt and sometimes things just stop working. The latest thing for me was that the version: latest doesn’t work when using the pkg.installed module. I liked keeping certain things at latest but now I’m going to end up doing pkg upgrades with a salt call.
I haven’t used Chef enough to really know. I do know it will perform configurations in order, which was a selling point to me. Unfortunately it’s all Ruby and I’m just not a fan of Ruby. I learned enough with puppet to make a few plugins, custom facts, etc but I didn’t want to learn it just for Chef. Sorry Ruby and Chef fans! The one thing that stay in my mind about Chef is that they have kitchen and probably the best testing tools.
So, which one?
As you can see nothing is perfect and there are pros and cons to each of them. My main suggestion is to try to use config management and never SSH into servers(have good logs!. Pick something, learn it, find the patterns you want to use with the tools and set standards throughout your organization to use them.
Now, if you want to know what I really think…
Salt for configuration management, Ansible for any jenkins jobs(builds/deployments) and provisioning of images.