Otter Documentation

Otter's Execution Engine

To monitor, configure, and orchestrate your infrastructure, Otter uses an advanced execution engine that's capable of running thousands of different operations and scripts on thousands of different servers. If you're already familiar with general scripting or programming concepts than much of Otter will be familiar to you.

Otter's execution engine is an integral part of Otter itself, but it's also incorporated into Romp (a stand-alone, command-line tool) to run plans against the local machine for testing or other purposes.

Operations

Operations are the tasks that the execution engine will run on a server. Otter ships with dozens of built-in operations and you can add more through Otter Extensions.

Regardless of where the operation comes from, there are two fundamental types:

  • Ensure – an operation that defines a desired state of configuration, gathers configuration information from a server, and if the actual and desired configuration differ, then configures or changes something on that server so that it matches the desired state
  • Execute – an operation that does or changes something on a server

You can use either of these operations in any type of plan, though in an ideal world, you would only use ensure operations in configuration plans, and execute operations in orchestration plans.

Declarative vs. Imperative

Most programmers are familiar with "procedural" (imperative) programming: essentially, describing the specific steps that must be taken to accomplish the goal. The declarative approach, however, focuses more on describing the desired goal. Some Infrastructure as Code tools mandate a single approach, but Otter supports both approaches.

Ensure Operations

Ensure operations all start with the word "Ensure", and they are designed to be idempotent, which means they can be run over and over again with no side effects. This enables you to create declarative configuration plans that simply describe the desired state of configuration.

For example, the Ensure-File operation, as the name implies, ensures that the file you describe exists (or does not exist) at the location you specify. If it's exactly as it should be, then the operation will not do anything; but if it's different, the operation will bring it to the desired state.

Execute Operations

Execute operations start with verbs like "Get" or "Create", and they are designed to perform a particular task, which makes them imperative or procedural in nature.

For example, the Create-File operation will create the file you specify, and may raise an error if you don't specify to overwrite an already-existing file. In some cases, the difference appears to be entirely semantical, as the same goal can be accomplished with either operation.

  • Declarative (Ensure-File)
  • Imperative (Create-File)
Ensure-File hdars.txt (
  Text: hello world!
)
Create-File hdars.txt (
  Text: hello world!,
  Overwrite: true
)

While using the right semantics are very important to help others understand your goals, the behavior is slightly different depending on which type of plan the operation is in.

Configuration Plan Runs

When running a configuration plan (either routinely or as a job), the execution engine will first perform a "collection run". In this run, the ensure operations will only gather configuration from a server, and then store that configuration and report if it's different than the desired configuration. It's through this mechanism that you can see the actual configuration of the servers:

Otter Configuration Details collected

Note that only the details you specify in the ensure operation are collected and compared; this means that you only see what was important to you.

When the execution engine performs an "execution run" against a configuration plan, only a minimal set of operations are executed:

  • Ensure operations that reported drift
  • Execute operations in the same (or nested) block of an ensure operation that reported drift

For example, consider the following block in a configuration plan:

  • Visual Mode
  • Text Mode (OtterScript)
Otter Configuration Plan Block
##AH:UseTextMode
# Ensure HDarsSite
# We need to restart the application pool and wait 5 seconds if the deploy path changes, otherwise we get dropped transactions
{
    Stop-AppPool HDarsAppPool;

    Sleep 5;

    Ensure-Site HDarsSite
    (
        AppPool: HDarsAppPool,
        Path: c:\websites\hdars$HDarsVersionNumber
    );

    Start-AppPool HDarsAppPool;
}

}

When the $HDarsVersionNumber changes (part of the Ensure HDars Site operation which can be seen in text mode), the site will change -- but before doing that, the previous two operations will run because they are in the same block. This behavior lets you balance ideal- and real-world configuration problems.