For those of you who are taking a look at Chef, we wanted to give you a run down of some of the things that make it awesome.
Chef is Apache Licensed
As an Open Source company, Opscode is dedicated to the idea that the best way for us to preserve our rights is to give those same rights to the community. We wanted to make sure that everyone who wants to use Chef (or Ohai) can use it in as many places, and as many ways, as possible. If you write automation with Chef, or link to it directly as a library, there are no limitations on what you do with your code.
You are free to do what you like with Chef – with our blessing and support.
Resources have Actions
Resources in Chef have many idempotent actions. For example, files can be created, deleted, or touched; services can be enabled, disabled, started, stopped, restarted and reloaded. A single resource definition can take multiple actions – a service can be both enabled and started, for example. Any resource can be notified to take any action by any other resource – for example, an HTTP request could be sent when a file is altered. A resource can appear many times in your recipes, each time taking a different action.
Chef makes as few decisions for you as possible, and when it does, it’s easy to make it change its mind
Chef assumes that you know best how your infrastructure is put together. When we were faced with questions like: “How do we know which Provider to use for a given Resource?” We always tried to answer with “The least surprising and most helpful thing as the default, configurable at runtime”. We never want to put people in the situation where they know what they want Chef to do, but it’s impossible to accomplish it because Chef is opinionated.
The result of this balancing act is that you very seldom need to repeat yourself, and that doing the most common things in Chef is very straightforward. But when you need to change Chef’s mind, you can – the system never second guesses you.
Dependencies, Ordinality and Expectations
When you are configuring systems, order matters. If you have not installed Apache, you can’t start configuring it, and you certainly can’t start the daemon. Configuration management tools have been struggling with this problem for years – and we think Chef hits the sweet spot.
Nodes in Chef apply lists of recipes, which in turn specify resources. Within a recipe, resources are applied in the order they appear. At any point in a recipe, you can include any other recipe – assuring that all of its resources are applied before continuing (Chef is smart enough never to apply the same recipe twice.) You specify dependencies only at the recipe level, not the resource level.
This means that you only track dependencies between high level concepts – “I need Apache installed before I can start my Django Application”. It also means that, given the same set of Cookbooks, Chef will always execute your resources in the same order.
It uses Ruby as the configuration language
Our experience building fully automated infrastructures brought us to the conclusion that the only way to get a configuration management system flexible enough to deal with all the permutations, gyrations, and odd requirements present in the real world was with a third-generation programming language. We needed to:
- Be able to integrate the system with our Applications directly (or via simple service calls).
- To reach out to external data sources as first class citizens, using whatever API makes sense.
- We needed to be able to utilize the full array of modern programming constructs and data structures, like Hashes and Objects.
Most importantly, we don’t know what we’re going to need it to do, but we need it to get out of our way as much as possible when we find out. A true DSL, by definition, can’t really do that – it is specific to its domain, and therefore must be bound by its domain.
At the same time, you need to keep the simple things simple. We put as little as possible between you and the resources you want to manage. For example:
package "apache2" service "apache2" do action [ :enable, :start ] end
Is all it takes to make sure a version of Apache is installed, enabled at boot, and running. If it’s something that should be easy (and all the configuration management primitives are easy), you don’t need to know you’re using Ruby at all.
(We have lots more to say about this, and we’ll be posting it on this blog in the days ahead.)
Clients are thick, the Server is thin
Chef does as much work as possible on the Chef Clients. The Chef Server is built to handle the easy distribution of data to the clients – the recipes to build, templates to render, files to transfer – along with storing the state of each Node. This orientation makes for a system that is easy to scale and extend – the work of deciding how to configure your infrastructure is distributed throughout your infrastructure, rather than centralized on set of configuration management servers.
The server is so thin, in fact, that most Cookbooks can operate in a Solo mode – run unchanged entirely without the need for a Chef Server at all (you do lose some of the benefits of Chefs integration capabilities when you run in this mode, but hey – TMTOWTDI.)
Node state is persisted between runs
After each Chef run, the state of the Node is persisted to CouchDB, and its attributes are made searchable via a full text search engine. This means it is possible to write Chef Recipes that span system reboots, that modify other attributes, or utilize multi-run state in any way you can dream up. This data is also available to your infrastructure via a simple REST interface – just call it if you need it. This is a key component of our next point…
The rest of your infrastructure and applications are first class citizens
Chef has the ability to integrate with external data sources and systems easily, and to expose information about your infrastructure to other applications. In the near future you’ll be able to send actions to resources under management easily, to ask Chef to re-configure a node (or nodes), and more. You can look directly at the state of your application, and use that information to configure your infrastructure. (Think load balancers, reverse proxies, monitoring systems, etc.)
When you use Chef to automate your infrastructure, you gain the ability to search across all of the systems under management via a simple REST API. This kind of integration can happen right in your application – rather than manage a list of memcached servers in a configuration file, you can just ask Chef directly for what memcached servers your application should be using.
We’re only at the start of what we have planned for Chef in this space – we have a lot more coming.
OpenID for Authentication
Chef utilizes OpenID for Authentication of the Clients. This feature also allows you to easily break apart the functionality of the Chef Server into multiple discrete clusters. By utilizing OpenID, the Clients can have a single place to authenticate, even if they are talking to many servers during a single run. In addition, managing the OpenID Registrations can be done from within the Chef Server UI, making management of new nodes trivial.
This is also a boon for infrastructures that are in multiple data centers, or that span both physical and cloud infrastructures. You can have a single canonical OpenID cluster, while having local servers that distribute Cookbooks to your clients – your servers have a single unique identity when they utilize Chef, no matter what your architecture needs are.