Flabbergast Configuration Language

Making configuration files less o_0

View project on GitHub

Configuration of Applications, Servers, and Containers

Complicated applications, deployed on multiple servers, have complicated configurations. How do you describe the configuration of a single part of that system, and all the layers underneath, and get it right? Once you have that right, now make a testing environment, or migrate to a new cloud provider. To get a background in why configurations are getting complicated, watch Configuration Pinocchio, presented at SREcon15 Europe.

Flabbergast makes this easier: it helps to describe configuration and it can handle the whole stack: from application to metal. Flabbergast provides a flexible template system to compose and recompose configurations and generate an output description, in any format you need. It happily nests systems together: the templates for an application and a container manager can be married with a minimum of fuss and “plumbing”, copying data from one place to another.

What it is and isn't

Flabbergast is two things: a programming language geared to generating configurations and a library of templates to help generate correct configurations before they are deployed. Unlike Chef or Puppet, Flabbergast doesn't deploy configurations; it's a system for describing configuration. A way to explain the state of the world to push out, through whatever means suit your application.

Bascially, you write a Flabbergast program that generates some complicated output file.

As a language, Flabbergast is a little unusual. In most languages, it's your job as the programmer to move data around through parameters, arguments, fields, and closures. For configuration files, you don't want to have to shuttle information around, so Flabbergast does it for you. It uses contextual lookup to find information so you can define things where it makes sense and not worry about copying it to where it gets used.

Getting Started

For a quick introduction, have a look at the primer slide deck. To really get started, take a look at the manual. There are some serious examples and some fun Rosetta Code examples. The API docs are also available.

If you are on Ubuntu or Debian, it's a snap using a PPA. The most recent version is also posted to Maven Central. Follow the installation instructions.

Here's a small example for generating an Apache Aurora configuration.

aurora_lib : From lib:apache/aurora # Import the Aurora library.
cluster : "cluster1"
role : "jrhacker"
resources : {
  cpu : 0.1
  ram : 16Mi
  disk : 16Mi
}
hw_file : aurora_lib.aurora_file { # Create an Aurora configuration file
  jobs : [
    job { # Create a job. This could also be aurora_lib.job, but we have nothing else named job.
      instances : 1 # One replica of this job should run.
      job_name : "hello_world" # Provide a friendly job name.
      task : aurora_lib.task {
        processes : { # Define the processes ⋯
          hw : process { # ⋯ using process template
            process_name : "hw" # The name of this process will be hw
            command_line : [ "echo hello world" ] # The command line we want to run.
          }
        }
      }
    }
  ]
}
value : hw_file.value # Flabbergast is going to dump this string to the output.

One of the things that makes Flabbergast special is it uses contextual lookup, that allows you to define thing where they make sense for your needs, rather than what the original author imagined. So, you can write the above config as:

aurora_lib : From lib:apache/aurora
cluster : "cluster1"
role : "jrhacker"
resources : {
  cpu : 0.1
  ram : 16Mi
  disk : 8Mi
}
hw_file : aurora_lib.aurora_file {
  jobs : [
    job {
      resources : {
        disk : 16Mi This disk resource will be used since it is “closer”.
      }
      instances : 1
      job_name : "hello_world"
      task : aurora_lib.task {
        processes : {
          hw : process {
            process_name : "hw"
            command_line : [ "echo hello world" ]
          }
        }
      }
    }
  ]
}
value : hw_file.value

and get the same result. Flabbbergast's contextual lookup will find the “closest” match, so you can shuffle your definitions to share things that should be shared without having to copy variables around.

Have a look at a sophisticated Flabbergast+Aurora example that makes use of Flabbergast's lookup to provide multiple geographic configurations, repeated server configuration, service discovery, and testing configurations.

Comparison

Language Flabbergast Coil HOCON Jsonnet NixOS Pan Pystachio
Paradigm Functional Functional Imperative° Functional Functional Imperative Imperative
Side-effect Free Yes Yes No Yes Yes No Hybrid°
Inheritance Prototype Prototype Prototype Prototype None Class-based Class-based
Typing Strength Strong Weak Weak Strong Strong Strong Strong
Typing Enforcement Dynamic Dynamic Dynamic Dynamic Dynamic Hybrid° Dynamic
Schema Validation None None None None None Assignment Request
Turing Complete Yes No No Yes Yes Yes No
Scoping Dynamic Lexical Lexical Lexical Lexical Lexical Hybrid°
Default Propagation Scope, inheritance Inheritance Inheritance Inheritance Operator Inheritance Inheritance
Output Format Text, Custom Python objects Java, Python, or Ruby objects JSON Java objects JSON, XML Python objects

° Depends on context. See SREcon15 Europe Configuration Pinocchio paper for details.

Support and Community

We are on the Internet, and plan to stay there. You can try FreeNode IRC in #flabbergast, Google Groups, Twitter, Google+, or GitHub.