Before I get into the discussion allow me to introduce myself. My name is Andrew Yarrow and I’m a member of the Isos Technology Atlassian team. Prior to coming to Isos, I spent a few years working for a software development shop, starting as their Mac support person and adding on responsibilities as time went on. While there, we selected and I started to learn about configuration management using Puppet. I thought I’d take some time to share with you my thoughts about SaltStack vs. Puppet.
The overpowering thought when I start to think about SaltStack vs. Puppet is you can’t go wrong with either one. The only way you can go wrong in this day and age is to not use a configuration management tool. If you aren’t using one, then you are clearly still treating your servers as pets (https://blog.engineyard.com/2014/pets-vs-cattle) and I would strongly advise you to humanely put down your pets and get into the cattle herding business!
Lets start by talking about why we chose Puppet in my previous life. At the time, I was working with a senior engineer who was very comfortable working with Puppet and felt that the syntax lent itself more to learning for a newbie. The documentation and community were well thought out and easy to navigate and they had a pretty robust “Learning” module by way of the Puppet Labs Learning VM (https://puppetlabs.com/download-learning-vm-b). I spent a couple of hours going through the Learn sections of puppetlabs.com and was off to the races. Another reason for choosing Puppet, was that it was a mature project offering both an open source and enterprise versions. They seemed to be setup for success.
Fast forward to today, and I’ve set out to learn SaltStack in my time so far at Isos. My first step to learning SaltStack was to start reading the documentation (http://docs.saltstack.com/en/latest/index.html). Coming from the documentation provided by Puppet Labs, I have to say that the documentation from SaltStack is…awful! It’s dense, hard to navigate and hard to follow. Some of the documentation is very substantial and includes more information then you’d ever need, while other parts leave you looking for more information. As an example I couldn’t seem to find a quick and dirty section that discusses the differences between a pillar and a grain. These seem like simple concepts now that I’ve become more comfortable in SaltStack, but would be worth an introduction earlier in the documentation.
There are a few other resources out there that I can recommend for learning SaltStack and to get questions answered. First, I found a great book (http://amzn.com/1784394602) on Amazon that breaks things down in a much more organized manner than the online documentation. I also found that for questions, the Salt IRC Chat (https://www.saltstack.com/resources/community/) is very helpful despite the one or two salty people in it. Most of the people there are very responsive and willing to discuss your questions. Here are a couple of other resources that I’ve found invaluable:
- One of the first things I was told about Puppet was the Type Reference page was one that I should bookmark because I would use it constantly. I’ve found the same to be true about the SaltStack Full list of builtin state modules: http://docs.saltstack.com/en/latest/ref/states/all/. Look how many there are! I’m pretty sure I’ve used less than 2% of them. The potential!
- Puppet Forge offers a lot of pre-built modules that can be used within Puppet and it took me a bit of time to find the equivalent in SaltStack, because who wants to recreate the wheel? The Salt version comes by way of the Salt Stack formulas found on GitHub (https://github.com/saltstack-formulas). Coming from Puppet, these formulas leave a bit to be desired, but are often a solid start nonetheless!
After reading through the book and pushing to write up my first state, I really want to give kudos to the people who have devoted their time to SaltStack. It seems like they took some time to study some of the other configuration management tools and they’ve incorporated a lot of stuff. Here are some of the useful and cool parts of Salt that I’ve discovered so far:
- Salt Bootstrap (http://docs.saltstack.com/en/latest/topics/tutorials/salt_bootstrap.html) - when I started reading this section of the book, I just smiled. In my previous life we had written something similar that would install puppet and get it all connected to the Puppet Master, but this is a whole different level. It lets you install a Salt Master, setup a Salt minion, install random packages you might need, install extra packages and more. I always wondered why Puppet didn’t have an easy and operating system agnostic method to get a node setup, and the SaltStack team heard my prayers!
- watch_in and require_in (http://docs.saltstack.com/en/latest/ref/states/requisites.html#the-in-versions-of-requisites) - when writing modules in Puppet and now states in Salt, I try really hard to make them as multi purpose as possible. Pillar-ize when possible and reuse as much as possible, again why recreate the wheel? Here was my first use case of “watch_in”. Our Salt configurations are written to sometimes include nginx depending on the desired configuration. I recently wrote a new state to be included in our SaltStack configuration and needed to setup a conf file within sites-available for nginx. I did this entirely within the apps state and never touched the nginx configuration. But I needed to be able to restart nginx so that it would pickup the new conf file, and the symlink in sites-enabled. This was so simple with watch_in! After adding the symlink, I simply added watch_in that pointed to the nginx service and nginx was rebooted. This allowed me to let the nginx state handle the nginx specific stuff, and each app handle their own conf files.
- Pillars (http://docs.saltstack.com/en/latest/topics/pillar/) - These really took some getting used to coming from Puppet. For a module in puppet, you often passed variables in that handle configuration for that module. As far as I can tell, Salt doesn’t work this way. Instead a state has a matching set of pillars, and then you can also assign pillars to minions or groups of minions. One cool trick I found buried in the SaltStack documentation was this little gem: This lets you get a Pillar, but if it is undefined then you can set a default. This is way cleaner and easier then using an if / else.
There are a couple things on the horizon for me related to Salt that I’m chomping at the bit to tackle.
- Salt integration with Foreman (http://theforeman.org/plugins/foreman_salt/2.0) has hit version 2.0 and is nearly at feature parity with Puppet. Foreman is a really cool tool that provisions, configures, and monitor that configuration all from one nice web interface. It will let us spin up nodes on AWS (and a bunch of other public and private clouds), assign pillar values, and then provides a reporting layer on top.
- GitFS for Salt environments (http://docs.saltstack.com/en/latest/topics/tutorials/gitfs.html#branches-environments-and-top-files) will allow us to have different environments enabled based on our main salt repository. We can test modules in development while the production configurations are protected and keep everything humming along nicely. In my mind, this is a must have when running infrastructure as code. Everything circles back to the code in source control and with GitFS it’s automatic! This replicates the functionality of r10k for Puppet, a tool I could not live without.
These are my initial thoughts after spending a few weeks with SaltStack and I look forward to more in the future. I hope to see any SaltStack converters on the IRC channel!