Related Content

Support Questions

Tags

A Comparison: Chef vs Otter

KB#1110: Last Updated Mar 04, 2016

Chef and Otter are both infrastructure automation products, and if you only read the marketing bullets, they'd probably sound identical.
But they're quite different products, and this article compares and contrasts the products and the philosophies behind them.

Moreover, there's nothing wrong with having and using both - in fact, many organizations have Puppet, Chef, and Otter, because they all serve different needs for different groups.

While we are not Chef experts, we've done a ton of research on Chef when building Otter and, more recently, for this article.
Please let us know if something is inaccurate.

Quick Aside: Chef vs Puppet

Unlike Puppet, which was built as a Linux Configuration Manager, Chef was built
as a "systems integration framework" to assist infrastructure automation specialists (originally, the consultants who built Chef itself) configure Linux-based servers and components.

If that sounds like six of one, half a dozen of the other, that's because ultimately, Puppet and Chef are different approaches to the same, Linux configuration problem,
and ultimately achieve the same results:

In Puppet, you write a manifest file using PuppetScript that declares a desired state of configuration.

In Chef, you write a recipe using Ruby that describes the steps required to configure a server.

We mention all this because the reasons that people choose Puppet over Chef, or choose Chef over Puppet have been documented for years, and these were key considerations when we designed Otter.

Chef requires a proficiency in Ruby to do anything but trivial configuration tasks

Chef's architecture and components are much more complex to understand and manage

Chef's complexity can lead to large code bases and complicated environments

Chef has a very steep learning curve and requires training

In addition, Otter addresses challenges that both Puppet and Chef share, including Windows and Orchestration.

Linux Configuration Management for Ruby Developers

Chef was built by experts, for experts; as such, ease of use was never a design consideration.

Requiring expertise is not a problem when your organization is fortunate enough to hire only experts, like many of the early and outspoken Chef adopters. However, most organizations simply can't dedicate the resources to build and maintain the required, in-house expertise.

The "maintenance" is key --- even if the initial "DevOps" team is successful in rolling out a complex system, the learning curve of that system will even more complex than a greenfield installation of Chef.

Otter was built with ease of use in mind, and actively encourages its users to build simple plans that others can maintain.

The Windows Challenge

Although Chef and the community have built a lot of Windows modules, the tool was never designed with Windows configuration management in mind, and Windows support often feels second-class.

Windows and Linux are very different; not just technologically, but philosophically. Although Windows has been lately offering administrators better command-line, scripting, and detachable components, they will always be two very different operating systems.

Otter was built with from the start with first-class Windows support (including tight integration with PowerShell), and
was built using Windows-friendly technologies (.NET), and doesn't need to go through layers of Ruby for core functionality.

The Orchestration Challenge

Although you can create recipes using Ruby, doing orchestration
– that is, getting specific servers to do specific things in a specific order, like deploying large, multi-tier applications – is extremely challenging and awkward with Chef.

This is because servers managed by Chef are responsible for configuring themselves; essentially, they routinely ask the central Chef repository for the latest Ruby scripts, and then run them
as needed. This model means that the central server cannot tell which servers should do things in which order.

While Chef's new Delivery Product attempts to make this easier, it's still an afterthought that utilizes the same, self-configuration model.

Otter's execution engine approach does not have this challenge by its very nature: the central Otter server runs commands
remotely on each remote server, and can explicitly control the order in which things happen on servers.

Lack of Visibility

Chef's learning curve is a barrier to implementing the collaboration aspects of DevOps; with knowledge concentrated to just a few, expert engineers, those specialists become a bottleneck in getting information on how infrastructure is modeled, and how servers are configured.

Otter was built to visualize complex configurations and let anyone dig into the details, while at the same time giving administrators the flexibility to restrict sensitive configuration.

Change Management and Compliance

Chef's developer-heavy design means that change management is handled in developer-friendly way (i.e. through a Git repository), and compliance isn't even an afterthought --- it's a separate product.

For some developer-heavy organizations, the idea of automatically applying configuration changes to dozens of production servers by syncing a Git repository is a dream. For governance and compliance personnel in enterprise organizations, that's a nightmare.

Compliance is built in to Otter. Servers can be configured to automatically remediate drift or simply report on it and give you the option to schedule a job to automatically remediate the drift. These are all first class concepts, as opposed to afterthoughts.

Chef's Ruby Libraries vs Otter Plans

Ruby is a general-purpose programming language, which makes it difficult to compare and contrast to OtterScript, which is a language designed specifically for the purpose of configuration management and infrastructure automation.

There's no question that a general-purpose programming language offers near-infinite flexibility, and that's precisely why Otter has such
tight PowerShell/scripting integration: when the high-level execution engine isn't the right tool for the job, just PSExec what you need.

Simplicity aside, OtterScript does have distinct advantages over Ruby, and most other general-purpose programming languages. Of course, with the visual code editor, you won't have to spend any time learning a specific syntax.

Implicit, Quote, and Swim Strings

Data is a first-class concept in Otter, and to help contain values without worrying about escaping, OtterScript offers
several syntaxes
for string literals:

Implicit – no quotes at all

Quoted – single- or double-quoted

Swim – multi-line strings while choosing your own delimiter

And OtterScript uses the grave apostrophe (`) as the escape character instead of a backslash, which avoids so many headaches when trying to represent file paths.

Seamless Remote Execution & The Context Stack

OtterScript does not need to run on remote servers in order to orchestrate them. The execution engine already has the concept of remote execution built-in, which means running a PowerShell script on all configured servers is as simple as this:

The above statement used a context-setting statement above; although this isn't something you'd do in a configuration plan, in an orchestration plan, the notion of the context stack makes writing complex orchestration plans simple.

Built-in Execution Status

Executions (i.e. plan/OtterScript runs) can end with one of three statuses: normal, warning, or error.

By default, the execution status works exactly like you'd expect – an uncaught error will terminate with an error status, and operations that log warnings will yield a warn status. But you can also explicitly set the execution status at any point during a plan execution with a simple statement (warn, force warn, or error).

Unlike a "throw" statement, this does not impact control flow (unless you explicitly test for it in an If/Else block), only reporting.

Logging as a first-class concept

Logging is such a first-class concept in Otter that it's not only an in-built statement, but the blocks you create actually directly translate to a collapsible logging scope.

Just add a comment at the top of a block, and that will become the collapsible scope.

Asynchronous Execution (Parallelism)

Multi-threading and parallelism is never easy in any language, but we took inspiration from one of the simplest and most powerful patterns: async/await.

# Execute Database Nodes
foreach server in @ServersInRole(database-nodes)
{
# these will take an eternity to run, so run in background
with async
{
PSExec >> some really long-running script >>;
}
}
# Execute Web Nodes
foreach server in @ServersInRole(web-nodes)
{
PSExec >> some reasonably short script >>;
}
# Hopefully database servers are caught up by now...
# but wait just in case
await;

You can even set and await on a specific async token, as to allow for multiple groups. And best of all, error handling "just works" with this pattern – just put a try/catch around the await.

Retry and Timeout as a first-class concept

In most general-purpose programming languages, a retry requires nesting a loop, a try/catch, and a couple if/else statements. With otter, it's a single statement: