Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I have to respectfully disagree. I try not to take sides in these issues because the software I make all works well and co-exists with Puppet, Chef, etc. But I feel I need to voice my opinion here.

I _love_ the explicit ordering of Puppet. It is one of my favorite features over other options. I'll explain why I think it is a good thing.

For credentials to add some sort of credibility to this post: I worked for 4 years as an ops person managing not small (but not big) infrastructures for multiple companies ranging from 10 nodes up to 200 nodes. Some organizations used Chef, some used Puppet, and I even used Salt once. I created and maintain Vagrant and Packer, both of which integrate deeply with all major configuration management systems, so I have to know how they work decently well to be able to maintain that.

Let's use Chef for the remainder of this post, but please don't take this post as saying "Chef is bad. Puppet is good." That is false. I'm just using Chef as an example where ordering is implicit (based on the order resources appear in a recipe and run list).

The explicit ordering of Puppet makes it very clear exactly what a resource depends on. When training junior ops, I was frequently asked "so I use requires/notify/etc. to tell Puppet what order to do things?" And I would say NO! That is the _result_, but the purpose of requires is to list what the resource has as a logical _dependency_. For example, a common problem with junior puppet devs is to say "Oh, I'm making resource C which depends on resource B and A, but since B depends on A, I'll just put 'B' in the requires list." That is _wrong_. Logically, C depends on B and A, so put both there! Don't think about ordering, think about requirements/dependencies.

Given this, Puppet is so great. You can look at any resource and say "oh hey, this depends on ONLY these list of things." Sure, the dependencies may have their own dependencies, but the resource in question doesn't care about that. Example: this file requires that this service is installed. That service might require, say, RubyGems, but the file doesn't care! Its not an immediate dependency of the file.

With Chef, on the other hand, I would see "okay, C happens after B and A, but does C _really_ need to happen after A?" I don't know. I can't answer that. It requires much deeper domain knowledge of that infrastructure to answer that question. This leads to more of a nightmare [for me] months down the road, when I don't quite remember if something needs to happen after something else.

With Puppet, as a style rule, I require all ops engineers list _all_ requirements (exhaustive require clauses) whenever they're working. Then, months down the road, you can move around anything you want. You know if you broke something because Puppet will tell you (before it runs, during the 'compilation' phase).

Personally, I prefer this sort of explicitness.

I understand that some don't like this, but I like it. And people can like it. I don't believe either way is STRICTLY better/worse. I felt my opinion needed to be shared.



This sounds like a question of how declarative your deps are, with Chef and Puppet picking different points on the scale.

I can relate that with Babushka now, we commonly rely on ordering of requirements (A <- B, C in that order!) at times when we should really have one of those requirements require the other (A <- B, B <- C). This works fine for the original purpose, but leaves minefields floating around when you want to reuse deps for another project.


Hm, part of my consulting agreement when I did Puppet was that I could re-use my own set of Puppet modules (which I never did open source). I shared the same set of Puppet modules among many clients and never had issues with "minefields" because of my explicit requirements.

Therefore, I think this comes down to how you design your Puppet modules.

Personally, I design my Puppet modules much in the way that Jamie Windsor designs Chef cookbooks and talks about in the ChefConf keynote: "The Berkshelf Way".


One nit to pick here is that I'd say that Chef is 'explicit' about ordering (I explicitly say exactly what is going to happen), while Puppet I would call 'implicit' based on solving a dependency graph and a bit of random hash order evaluation.

This is actually one of the founding principles of Chef in that Adam Jacobs got tired of, in large systems, when you get one link in your dependency tree wrong you wind up with code which will pass tests and get deployed to prod then accidentally get broken the next day as the random ordering changes.

Also, Chef does have dependencies between cookbooks and we do depsolve at that level. You can even construct things so that your base role that does most of your user account creation, ntp, dns, mail config, etc -- which is most of the time orthogonal to your app -- does not need to be a dependency of your application cookbooks. If you're deploying a rails app you can make that cookbook depend mostly just on installing ruby and deploying from github and you can test that, tightly, in isolation on a vagrant VM with test-kitchen. You can also setup more complicated integration scenarios where your nginx load balancer cookbooks don't depend on your apps, and your apps don't depend on your nginx config, but you can have integration tests for your nginx loadbalancers that brings up both in a virt and makes sure that you can load balance your app -- again, though, without sucking in every person's ssh keys in the org to set it up.

And even though you're expressing dependencies, you're doing so in a array with an ordering to it, so that the dependencies reliably get solved in the correct direction, so that even if you don't specify the deps right, if you get the ordering correct it all works.

And for credentials, I started using CFEngine in 1999, I did most of the "base role" of Amazon's CM infrastructure from 2001-2006 (growing from doing config pushes to 400 servers in my department to 30,000 servers across the company), then I built a few more small CFEngine deployments of 1,000-3,000 servers before moving on to working at Opscode.

And my background with CFEngine -- which really invented the Prolog-style-Config-Mgmt that this whole article is about some 20+ years ago. And with the frameworks that I built on CFEngine I always imposed ordering so that you could read scriptlets from top to bottom and see what happened and then composed those scriptlets in runs that would execute in order. When we started out not doing that it was hugely confusing to newbies since actions would be taken in a seemingly random order in the file and that is not a natural way for people who walk into config management -- so we went out of our way to break the dependency-solving that CFEngine did and create something that ran almost exactly like Chef does (technically even more extreme, since there was no dependency resolution between "cookbooks" and while there wasn't an explicit run_list the order that files were included simply determined the order of execution).




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: