4 ms·
I've been using Chef for many years and have been pretty happy with how straightforward everything has been, but I am always open to other solutions. If you've
by usrme 7y ago
I've been using Chef for many years and have been pretty happy with how straightforward everything has been, but I am always open to other solutions. If you've used Chef, Puppet or Ansible, how would you say Salt differs from those?
Your comment has already inspired me to look deeper into Salt, but I am hoping you can lay out some general pros and cons as well. Thanks!
- cheald 7y agoI've used all three in the past. Chef was the first I used, many years ago. It's...complex. Despite being Just Ruby, the DSL takes quite a lot to learn, and I don't like that Chef is imperative rather than declarative. It also just seemed crazy verbose. It felt like it took ages to get my configurations right. For example, here's a community cookbook to install and setup NTP: https://github.com/chef-cookbooks/ntp/blob/master/recipes/default.rb https://github.com/chef-cookbooks/ntp/blob/master/recipes/de... I tried Puppet after Chef. It was better, but I always seemed to be spending more time fighting it than actually getting stuff done with it. It suffered from the inability to push states to boxes at will. It's probably more pure to do it periodically via cron, but when you have stuff to get done, sometimes you just want your state applied to a machine. Configuration was less complex than Chef, but still quite verbose. Because box state is "all or nothing" you end up with a pretty slow management system that felt really subject to bitrot. On the subject of complexity, here's the community NTP module: https://github.com/puppetlabs/puppetlabs-ntp https://github.com/puppetlabs/puppetlabs-ntp I like Ansible a lot. No real complaints about it, except that Salt is "Ansible++" with the command channel, reactor system, etc. Salt's just YAML, like Ansible. You have minimal logic available in YAML via Jinja, but it's discouraged by design; your state declarations are meant to _describe_ the state of the system, rather than to execute a series of explicit steps. Salt figures out how to bring them into compliance. You aren't meant to program in it, you're meant to describe in it. This makes states very straightforward and easy to interpret. By comparison to the first two, here's a similar formula for Salt: https://github.com/saltstack-formulas/ntp-formula/tree/master/ntp https://github.com/saltstack-formulas/ntp-formula/tree/maste.... Terse, simple, straightfoward. ntp/init.sls is the whole state that gets run - it just installs the package, marks the service as enabled, starts the service, and if there's a config defined, installs it. Templates can be colocated with the state definitions. Nothing too fancy, just yaml and plaintext configs. I can apply just that single state to a box (salt mybox state.apply ntp) or set of boxes (salt -G "os:Ubuntu" state.apply ntp) or I can do a pull from the box (on mybox: # salt-call state.apply ntp). I don't have to run the 479 states that apply to the box in sum; this makes incremental management of boxes very quick. You can use salt like Ansible via salt-ssh (shells into target box, executes states), like Puppet or Chef (operating in master mode, with agents that connect and execute states), you have the active command channel to your fleet, and you can do event-driven stuff with it, too. For example. we provision and renew LetsEncrypt wildcard certs on our Salt master. We have a Reactor set up that that watches for when a cert (on the master) is updated, which finds all machines subscribed to that cert and executes our `ssl.certs` state, which pushes the new cert out and executes any service reloads necessary to get the renewed cert into play. This lets us keep a small set of certs/renewals in a centralized location rather than having to worry about a bunch of scattered LE renewals all over the fleet. When we have to provision a new machine or a new service, we can just subscribe to the desired cert and we're off to the races - no need to do the LE provisioning each time we salt a new box. There's a lot to love about it. It's not without its bugs, but the Saltstack project and team are very active, and the project itself is Python, which is easy to read and write. I've had to debug things a number of times, but it's never too difficult. Been using Salt for years now, and I still think it's the best in class out there.
- usrme 7y agoMany thanks for your extensive reply! There's even more to consider now <3 EDIT: Can you vouch for the ease of use when configuring Windows machines as well?
- oneplane 7y agoWindows is supported as well, at least as a minion (a 'target'). You can run cmd and ps1 commands remotely, but there is no SSH support. This will be added later on when MS makes SSH a 'normal' integration and then salt can implement that as well. There are a number of Windows-specific states and if you have a universal state (i.e. making a directory in a specific place) the documentation will supply you with the things each OS does and doesn't support. For example, you can't set POSIX permissions on Windows, but if the FS is NTFS you can set an NTFS ACL.
- cheald 7y agoWindows minions are supported, but I'll confess I haven't done much with them. I manage Linux servers exclusively.
- apple4ever 7y agoInteresting thoughts. As an Ansible fanboy, I tried Salt just to understand it, and absolutely hated it. It was too complex to set up for me.
- cheald 7y agoSalt is definitely more complex than Ansible. Ansible wins the simplicity battle by a mile - for small or low-maintenance setups, I'd go with Ansible. Salt is way less complex than Puppet or Chef, though. However, once you have a decent number of things to manage, Salt becomes worth the initial setup cost, IMO. The hardest part about it is just learning the concepts - the difference between "states", "grains", and "pillars" is unintuitive, for example (states are what describe your system, grains are k:v data that lives on the minion, pillar data is k:v data that lives on the master), and it's not initially clear how states differ from modules (modules are "functions" that run, states wrap modules in a declarative syntax). Once it clicks, though, you have a seriously powerful tool at your disposal.