Before DevOps became a hot word in the industry, development and operations by definition were entirely separate and, without the cloud, new servers were manually provisioned.

However, according to our DevOps Pulse 2016 report, 40% of respondents said that today they deploy code a few times a week and more than 80% either have a Continuous Integration (CI) strategy, are in the process of implementing one or are considering the possibility.

Automation has been the key to making this happen. This automation has come in several forms: an unattended installation medium, a shell script setting required values, or maybe a version-controlled /etc directory. Whatever method you chose, the considerable effort usually went into preparing such solutions. And when a heterogeneous IT environment is involved, the difficulties only increase.

Eventually, people started getting fed up with all the shortcomings, and this is where configuration managers took over. This article compares two of the most popular tools: Chef and Puppet.

The Role and Benefits of Configuration Managers

In simple terms, configuration managers provide an abstraction layer between a machine’s raw configuration and its desired state by focusing on users’ goals instead of the tedious tasks necessary to achieve them.

For example, let’s assume you need the “First Ethernet interface to be configured with the IPv4 address of 10.0.0.1” instead of “File /etc/network/interfaces to be appended with the following content […]”. Such high-level instructions can be written as source code — in some cases, it is data rather than code, but let’s keep it simple — and can be stored in a version control repository along with the rest of the application’s code. This, in turn, allows for easier reproducibility and better insight into how the infrastructure should behave.

Configuration managers use well-defined language to manage all the operations’ needs, so knowledge can be shared between projects. Each time a new member of the team is hired, there is no longer a need to explain all the intricacies of a homebrewed system. Only the knowledge of a standard tool is required.

In principle, mature configuration managers don’t just write some data to some configuration files. They collect the facts about the nodes first and only act when a change is actually needed. The state of the systems is known and ready for inspection, so running the same command several times in a row will result in setting the state in the first run and doing nothing for the rest of the times, creating an efficient environment.

Giving some structure and composition to the overall view is also encouraged. Each application on a host and each cluster’s node may be described separately, yet they are orchestrated in the end. This way one person can experiment with a Java installation without interfering with another’s tweaks to a SQL server.

Requirements and Installation

Puppet and Chef, which were among the first configuration managers and continue to be popular, use Ruby Domain Specific Language, however, you do not have to be an expert Ruby hacker to use them. To get the best collaboration possibilities, learning and using version control (such as Git) is recommended.

Installing Chef and Puppet applications is straightforward for both platforms. Chef recommends installation via an (insecure) shell script whereas Puppet gives instructions on manually using supported repositories. Keep in mind that Puppet requires a working DNS setup for the orchestration of remote nodes, but you can always start its online emulator.

What is not so straightforward is the proper use of these tools. There are many third-party components that may require additional installation and configuration. Of course, if you do not need them, you may start with just the base installation.

Methodology

While both tools have similar goals, the means used to achieve them differ. One of the biggest differences is how resources are described:

Puppet uses a declarative language that is similar to JSON or XML. You describe the resource’s state but cannot intervene in how this state is achieved.

Chef uses an imperative language. This means you more or less have full-featured Ruby at your disposal.

The declarative nature of Puppet may seem constraining, but those constraints are usually for your own good. They challenge you to describe the desired state better as opposed to writing complicated procedures that soon become unreadable.

To use an analogy, using Puppet is like writing configuration files whereas using Chef is like programming the control of your nodes. If you or your team have more experience with system administration, you may prefer Puppet. On the other hand, if most of you are developers, Chef might be a better fit.

As shown below, both generally work in client-server mode, meaning that one or more machines (running servers) manage the configuration of the other machines using agents. Each of the agents is managed by controlled nodes, either as a system service or periodically (such as from cron).

Chef’s –local-mode serves well for getting used to the CLI tool as well as the recipes themselves. It requires almost no setup. Puppet is the opposite end of the spectrum. Puppet offers a similar experience with its apply command. To get the best of those tools, though, it is necessary to set up servers and agents.

Key Concepts

The configuration managers abstract the configuration files themselves, so you need to learn the terms that they use to describe resources and their orchestration. In Puppet, you create manifests and modules, while in Chef you deal with recipes and cookbooks. Manifests and recipes usually describe single resources while modules and cookbooks describe the more general concepts (a LAMP server running your application, for instance).

Examples of resources with which one can deal with are files, directories, network interfaces, and applications. Commands like mkdir, cat, and apt-get or yum are replaced with desired states (“present,” “absent,” “updated,” and so on). Instead of thinking in terms of incremental changes to the configuration, you just focus on the outcome and write it down.

Examples of resource definitions for a directory, a file, and a package are shown below:

Example #1 — Creating a Directory

# Puppet file { '/tmp/example' ensure => 'directory', }

# Chef directory '/tmp/example'

Example #2 — Writing Content to a File

# Puppet file { '/tmp/hello' ensure => 'present', content => "hello, world!", }

# Chef file '/tmp/hello' do content 'hello, world!' end

Example #3 — Installing and Enabling Apache

# Puppet class apache2 { # Package name differs between distributions. # Here we select appropriate one if $::osfamily == 'RedHat' { $apachename = 'httpd' } elseif $::osfamily == 'Debian' { $apachename = 'apache2' } else { print "This is not a supported distro." } package { 'apache' name => $apachename, ensure => 'present', } service { 'apache-service': name => $apachename, enable => true, ensure => 'running', } }

# Chef case node[:platform] when 'ubuntu', 'debian' # Update apt cache every 86400 seconds (that is once a day) apt_update 'Update the apt cache daily' do frequency 86_400 action :periodic end apachename = 'apache2' when 'redhat', 'centos' apachename = 'httpd' end # Install 'apache2' package package 'Install apache2' do package_name apachename end # Enable and start the service service apachename do supports :status => true action [:enable, :start] end

Available Tools and Integrations

Have you ever noticed that some projects or applications (for example, package managers) tend to use their own lingo? They mostly do this to distinguish themselves from others and to look cooler. Chef, with all the culinary analogies, is no different here. You deal with “recipes” and “cookbooks.” Tools are named “knife,” “Foodcritic,” and “Test Kitchen.” Depending on the nature of your working environment, this may seem either appealing or discouraging.

Puppet comes with its own collection of editor integrations. There are plugins for Vim, Emacs, Atom, Sublime Text, Visual Studio, JetBrains IDEs, and NetBeans. You may find such integrations for Chef, too, though none are officially endorsed on the project’s webpage.

Good practice requires writing tests for the code. The configuration is no different in this case. There are dedicated solutions for testing Chef such as Test Kitchen, whereas Puppet uses more standard tools (such as RSpec and Cucumber).

If you are already using other popular DevOps software, chances are Chef and Puppet could integrate well with it. Vagrant, Packer, and Docker support both client-server and agentless provisioning with either of the tools.

Besides provisioning, Chef also offers related tools such as InSpec for compliance automation and Habitat for application automation. All of these, along with Chef itself, integrate nicely into Chef Automate, which is advertised as the one-stop shop for automation. Chef Automate’s counterpart for Puppet is called Puppet Enterprise Console, and it is available for Puppet Enterprise customers.

Customization

Sometimes even the most advanced tool seems useless for your special needs. This is when you have to focus on the tool itself and shape it in your own way. Both of these configuration managers offer easy ways of doing this.

First of all, there is support for user-created modules and resources. Chef’s tutorial claims it is possible to learn to write new resources in sixty minutes (including testing). Puppet recommends reserving around three hours to dive into this topic in an instructor-led class. On top of that, the systems are open-source, meaning that you can change their behaviors by modifying their codes. The possibilities are thus endless and are limited only by your available time and knowledge.

Documentation and Community

Chef’s documentation is better structured and easier to follow. The tutorials are thorough and explain most topics with ease. You can start learning with a Vagrant VM, an Amazon cloud machine, or on an existing system. You can choose from the most popular host systems as well.

Puppet is also documented in an in-depth manner. Since the matters require better understanding, you should be prepared to invest your time studying much of the documentation before you begin your work. Puppet also provides courses and training. If you are looking for commercial support, it might make sense to enroll an online or even in person training course. Similar resources for Chef are available. If you need a proof of proficiency with either tool, both companies offer relevant services towards certification.

All in all, there are lots of articles and forum threads regarding both systems, so finding information should not be a problem. In addition, both Puppet and Chef have thriving communities. They offer the modules directory in the form of PuppetForge and Supermarket. They have similar followings on GitHub and are being actively developed.

Commercial Support

If you require commercial support, you are covered as well.

Keep in mind that the plans require you to have more than a handful of nodes. The annual costs (as of December 2016) are $120/node for Puppet Enterprise (with a minimum 10 nodes, free below the threshold), $72/node for Hosted Chef (with a minimum 20 nodes) and $137/node for Chef Automate. Additionally, there is 24/7 support available for Puppet Enterprise for setups with more than 100 nodes. The price is negotiable. As previously mentioned, training, courses, and certifications are available as well.

Final Notes

Of the two systems, Puppet is the older one. This basically means better stability and support. It might also be easier to find people skilled in it. There are some downsides as well. The declarative language may require some adjustment for people who mostly do coding.

Chef, being the younger project, may have a slightly more “modern” feel. It requires less of a traditional infrastructure, and it scales well. Its main differentiator comes at a price, though. Be aware that its freestyle imperative approach may lead to poor-quality code – don’t use Chef as an excuse for not taking the time to learn Puppet.