frebby
is a very, very simple Ruby script that generates JSON out of a Ruby
based configuration language. It is intended as an alternative to the numerous
attempts to write a more human-readable language for tool configuration (YAML,
TOML, HCL, to name a few).
In contrast to these other languages, frebby
is not a full blown parser.
Instead it takes a bunch of Ruby code, eval
s it and turns it into JSON. The
result can then be fed to basically anything that can read JSON.
Everyone has a different opinion on how powerful a configuration language should be. Some people prefer a very strict and foolproof language while others prefer full blown programming languages. For most, the answer is somewhere in the middle. This tool is aimed at those who sit quite far in the programming language camp and who feel YAML and HCL are lacking in possibilities.
-
Use all the power of a full programming language for tools that usually wouldn't support this (Ansible, Terraform, Packer, ...)
-
Keep all your infrastructure defined in one consistent language
-
Works with anything that expects configuration files in JSON format (or YAML, or HCL, since these are just supersets of JSON)
-
No dependencies (except Ruby, of course)
-
You need Ruby installed, and some level of Ruby knowledge will help also
-
It is another tool in you build chain and adds some level of complexity
-
There are some very good arguments for keeping the configuration for your infrastructure as simple and obvious as possible. Using a turing complete configuration language to set up the most critical parts of your infrastructure just asks for trouble. With great power and so on.
- Due to the way frebby uses (abuses?) the Ruby programming language, there are some quirks where it will not immediately work the way you would expect. See the relevant examples details.
At its core, frebby is just a very simple ruby script without dependencies. In
theory, it is enough to just download the main file and put it
anywhere in your $PATH
. However, this won't get you the additional customization
options. Instead there are more convenient options available:
Usually you will want to install frebby directly from rubygems:
gem install frebby
Once installed, usage is pretty simple: The frebby
command simply takes any
number of configuration files as input, either as arguments or from stdin,
and output JSON on stdout. There are no other arguments or configurations
to worry about.
frebby /path/to/config/file.rb /path/to/other/config.rb > /new/json/config.json
# alternatively:
frebby < /path/to/config/file.rb > /new/json/config.json
Aternatively, if you don't want to install Ruby locally, you can use frebby out of Docker:
docker pull oclaussen/frebby
docker run --rm -i oclaussen/frebby < /path/to/config/file.rb
Remember that you need to either pass your config files to the docker container via stdin or mount your working directory, so that frebby can find them.
Configuration for frebby is written in Ruby. The basic syntax looks like the love child of HCL and Chef's recipe DSL and should be immediately familiar to anyhone who has worked with either of them.
# Basic types (strings, numbers, lists, hashes) can be used just like
# in Ruby:
some_number 5
some_string <<EOF
This is
a very long
text
EOF
# Nested objects are created like this:
some_object 'some_nested_object' do
some_key 'some value'
some_other_key 'some other value'
end
# Lists of objects are created by repeated blocks:
some_list do
some_key 'some value'
end
some_list do
some_other_key 'some_other_value'
end
This example will produce the following JSON output (minus formatting):
{
"some_number": 5,
"some_string": "This is\na very long\ntext\n",
"some_object": {
"some_nested_object": {
"some_key": "some value",
"some_other_key": "some other value"
}
},
"some_list": [
{
"some_key": "some value"
},
{
"some_other_key": "some other value"
}
]
}
For some more detailed examples, see the examples.
It is also possible to exert a little more control over how frebby translates to JSON.
# There are a bunch of customization functions available, that will act whenever
# frebby tries to transform a key, value or the whole end result
# Every translation goes through all registered customization functions, and
# will apply the first one that returns a non-null result.
require 'frebby/hooks'
::Frebby.customize_key do |key, **_data|
'new_key' if %w[some_key some_other_key].include?(key)
end
::Frebby.customize_value do |value, **_data|
value.sub('value', 'thing') if value.is_a? String
end
::Frebby.customize_result do |result, **_data|
result['copied_field'] = result['copy_this']
result
end
some_object do
some_key 'some value'
some_completely_other_key 'some completely other value'
some_nested_object do
some_other_key 'some other value'
end
end
copy_this 'this value should be copied'
This example will produce the following JSON output:
{
"some_object": {
"new_key": "some thing",
"some_completely_other_key": "some completely other thing",
"some_nested_object": {
"new_key": "some other thing"
}
},
"copy_this": "this thing should be copied",
"copied_field": "this thing should be copied"
}
frebby also offers some more convenience functions that take care of common use cases. There are also some useful presets for existing tools. Again, take a look at the examples for some inspiration.
Copyright 2018 Ole Claussen
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.