Skip to content

Instantly share code, notes, and snippets.

@jkeiser
Last active December 23, 2015 09:49
Show Gist options
  • Save jkeiser/6617298 to your computer and use it in GitHub Desktop.
Save jkeiser/6617298 to your computer and use it in GitHub Desktop.
1 Minute To First Converge

1 Minute To First Converge

It takes a while to first learn Chef, even with http://learnchef.com. I'd like to get that time down. One of the big hurdles a new user encounters is the need for a server to do many important tasks. A second hurdle is a large amount of configuration and privileges the user needs.

I'd like to get learning Chef down to a 3-step, less than one minute experience of joy and success. And I don't want to do it by building special tools you only use when you're starting up; you should only be doing things that will stand you in good stead as you get more advanced.

The plan

Here's the 3-step of my dreams:

  1. Install chef omnibus (known 1-step install)
  2. Create a cookbooks/startmeup/recipes/default.rb recipe with a resource or two in it.
  3. chef-client startmeup

No setup besides the install. No configuration, no authentication, no server, no privileges. Pure recipes, up and running and getting value in no time.

This requires two things: first, we need a server (and I nominate chef-zero). We integrate chef-zero tightly (and invisibly!) with chef-client and knife. Yes, you need a server, and we'll GIVE you a server that you don't even know about. Second, we need users to be able to run chef-client by default WITHOUT root, which means changing some default configuration like repositories and caches to point to accessible places.

The command, again:

chef-client startmeup

  1. Don't require a server

The first thing we need is the option to start up a local chef-zero instance, pointed at the user's local repository. In this proposal, the chef_zero.enabled option will accomplish this. chef_zero.port allows you to decide what port (which defaults to 8889). When the chef-zero server is started, chef_server_url will be set, meaning all knife and chef-zero operations will proceed as normal. This should come with a command line option as well so that one can quickly switch between one's server and local mode.

A further enhancement would be to allow a range of ports to be specified, so that if one is taken, we will try to start up on the next one.

To avoid configuration, chef-zero needs to be the default when running in a local repository like the above, when no configuration file is specified.

Keys must not be required for Chef::REST (or invisibly supplied). When not supplied, requests will not be signed (and we let real servers return the requisite 401).

  1. Let normal users run chef-client by default

When users run Chef, by default it points to cookbooks and such in /var/chef/cookbooks. This needs to change. If no configuration file is found, Chef should first detect if it is running in a repository (by looking for a cookbooks/ dir just underneath or above it in the path) and set the chef_repo_path to that.

Even with the location of cookbooks and other data fixed, Chef still has some operations that touch caches in /var/chef/cache and the like. If no configuration file is found, Chef should set the cache to /.cache.

  1. Make the command line accessible

When running chef-client locally, it is convenient and intuitive to just type recipes out on the command line. We should allow non-named arguments, and treat them as an overriding run list.

It may also be useful to allow users to type filenames, so that tab completion comes into play, a la knife-essentials:

chef-client cookbooks/apache2

chef-client cookbooks/apache2/recipes/server.rb

cookbooks$ chef-client apache2

@lamont-granquist
Copy link

Mostly +1 on all the things. Definitely +1 on default paths to things being sane when running as non-root. I'm not sure exactly what to think about knife.rb == client.rb since technically those have different options and formats, but the overlap may make this work, although with that cause strict mode issues since chef-client has zero knowledge of all the knife cloud options you might encounter in a knife.rb? But definitely would like to see that annoyance resolved one way or another. Also +1 on having easy ways to fire up chef-zero and putting that in front of people first.

I'm not sure what to think about the command line options. That wasn't on the top of my list of things to fix, but I see how you're trying to get around creating dna.json files, and I agree with that. We've already got chef-apply that does something similar to that, and it feels like there's some kind of overlap there...

I don't have the hate that other people have on chef-solo. I'm dubious that we want to start running a server when people are using chef-solo specifically because they want fewer moving parts. I doubt that is what the chef-solo user is looking for. Their requirements are somewhat irrational, but I don't think its the best move to piss them off by taking away their toy because we know better than they do (I still viscerally hate the CFEngine community for that kind of attitude and is why I'm at Opscode). I think we should address the pain that support for chef-solo causes us by ripping all the search code out of the cookbooks and DI inject that information with wrappers anyway -- it'll make it nicer for chef-solo users and I always rip the default way search works out of the cookbooks that use it anyway because the roles aren't setup like I want (i.e. I started using the wordpress cookbook and massively forked it because the way it did search and the assumptions it made were not remotely what I wanted, and I doubt its very useful for anyone with other than the most trivial needs to wordpress site because it is all so highly opinionated -- so why would we architect our choices around chef-solo around that kind of poor use case?).

However, either way that bikeshed about chef-solo goes I think its irrelevant and orthogonal to if this is all a good idea or not. Go ahead and build the chef-solo-like-chef-zero-based-thing and once that is done we can argue about the merits of just calling that thing directly from a script stub named chef-solo..

@lamont-granquist
Copy link

looking at this horrible Chef::Config[:solo] block in the postgres cookbook, it is also dealing with this mess of setting up random passwords on first install, which is another antipattern and should be put into (encrypted) data bags, and ideally the recipe should be much simpler and just let you DI whatever data source you like for the initial postgres password... every time I see these kinds of nightmares in the cookbooks, though, it doesn't make me want to shoot chef-solo it makes me want to shoot the whole misguided approach... okay, </rant>

@jkeiser
Copy link
Author

jkeiser commented Sep 19, 2013

Thanks for the comments! One point: knife and chef-client actually use the exact same Chef::Config class, whether or not that's a good idea :) There won't be any strict mode issues; there are just options that work in one and have no effect in the other.

I don't care if chef-solo really goes away; I just want a functional alternative. If people passionately want to save it in its current form I will live; we can have a debate on the merits of maintaining that code (and the alternative codepaths it creates). It's certainly not key to the main thrust of the proposal.

@jkeiser
Copy link
Author

jkeiser commented Sep 19, 2013

On the other hand, I think it becomes obsolete because it becomes redundant, not because solo was a bad idea. It becomes obsolete because it provides a strict subset of the functionality you could have with Chef.

Running local cookbooks, without a server, is a great idea. Having an invisible server is just a means to that end in my humble opinion, and I won't have any issue at all if someone finds a way to implement all the functionality without involving an actual server! I think there are definitely ways.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment