Giter Site home page Giter Site logo

distill's Introduction

Distill

Puppet template engine using hierarchical substitution.

Description

A common issue in Puppet is that you end up with a lot of logic just to determine the configuration based on certain criteria. Also changing this becomes a problem since you need to re-test your code for every change.

In most programming languages it's common practice to keep Configuration separate from the actual code, this is why Distill came into existence too fill this gap. It consists of 2 part's the first is to template a configuration for hosts based on certain criteria's and the second part is to validate the actual result of these templates.

Additional advantages of this approach is that it makes it very easy to detect changes for host configuration:

  • When it was changed
  • What was changed
  • Who changed it

This does however assume you store your Templates in version control, which is highly encouraged.

Since Distill also comes with a Web REST API it makes the host configuration available too your own glue scripts in a very simple manner.

Examples

Example of an Substitution sequence.

Default -> Region -> Country -> Datacenter -> Business Unit -> Owner -> Host Group -> Host 

In the top level you keep default's and then substitute them with more and more granular values.

This is an example template that says for the Region EMEA call the Class resolv and pass the parameter dns_servers with the above values.

region/emea.json

{
    "resolv::dns_servers": [
        "192.168.1.1",
        "192.168.1.2"
    ]
}

This is an example template that says for the Country Switzerland call the Class resolv and pass the parameter dns_servers with the above values.

country/ch.json

{
    "resolv::dns_servers": [
        "10.0.1.1",
        "10.0.2.1"
    ]
}

This is an example template that says for Datacenter in Zurich Unset the DNS Server 10.0.2.1 and then merge the DNS server 10.0.3.1 instead.

datacenter/zurich.json

{
    "u:resolv::dns_servers": [
        "10.0.2.1"
    ],
    "m:resolv::dns_servers": [
        "10.0.3.1"
    ]
}

This is an example template that says for the Host Group mysql_server configure mysql client and server, additionally setup 2 users.

host_group/mysql_server.json

    "mysql::client::version": "5.0.1",
    "mysql::server::version": "5.0.1",
    "mysql::server::user::users": {
        "user1": {
            "host": "%",
            "password": "*6691484EA6B50DDDE1926A220DA01FA9E575C18A"
        },
        "user2": {
            "host": "%",
            "password": "*6691484EA6B50DDDE1926A220DA01FA9E575C18A"
        }
    }
}

This is an example template that says for the Host testbox setup an additional mysql user.

host/testbox.foo.bar.json

{
    "m:mysql::server::user::users": {
        "user3": {
            "host": "%",
            "password": "*6691484EA6B50DDDE1926A220DA01FA9E575C18A"
        }
    }
}

The output from the following will be an ENC in YAML format.

Output YAML ENC

---
classes:
  resolv:
    dns_servers:
      - 10.0.1.1
      - 10.0.3.1
  mysql::client:
    version: 5.0.1
  mysql::server:
    version: 5.0.1
  mysql::server::user
    users:
      user1:
        host: %
        password: *6691484EA6B50DDDE1926A220DA01FA9E575C18A
      user2:
         host: %
         password: *6691484EA6B50DDDE1926A220DA01FA9E575C18A
      user3:
         host: %
         password: *6691484EA6B50DDDE1926A220DA01FA9E575C18A
parameters:
  default: default
  region: emea
  country: ch
  datacenter: zurich
  business_unit: operations
  owner: user1
  host_group: mysql_server
  host: testbox.foo.bar
  distill_environment: production
  distill_server: distill.foo.bar
  host: testbox.foo.bar
  puppet_environment: production

In this fashion you can create a very fine grained configuration outside of Puppet. The whole idea is too keep Configuration separate from Code. Otherwise you have to re-test your Code every-time you make a change.

Features

  • Separate environment's with individual templates and substitution sequences
  • Web REST API
  • Standalone server, doesn't need to run on the Puppet server

Distill also supports some advanced field operators:

  • Unset field, array item, hash key
  • Merge arrays/hashes
  • Immutable ie. prevent a field from being substituted at a lower hierarchy
  • Reference other fields

Roadmap

  • Write an on-line tutorial with complete examples
  • Provide --diff option to changed hosts, that will print a diff for the hosts that has changed configuration
  • Rename Expand operator to Reference and implement a Copy operator
  • Rewrite in Ruby to enable better Puppet integration (other benefits include degraded performance and memory leaks)
  • Inline queries in ERB templates for details like which hosts use module X
  • Extend REST API to allow more complicated queries
  • MySQL database backend
  • Web front-end

Distill Schema

Validate configuration using JSON Schemas.

Description

Distill Schema is an extension to Distill that allows for the creation of JSON Schemas that can verify a configuration before it's applied to production.

This is usually done as a build step for the templates, using a Build Server like Jenkins.

Example

Using the Class mysql::server::user in the above examples for Distill a JSON Schema would look as follows:

Puppet Class

class mysql::server::user($users)

Distill output as Puppet YAML ENC

  mysql::server::user
    users:
      user1:
        host: %
        password: *6691484EA6B50DDDE1926A220DA01FA9E575C18A
      user2:
        host: %
        password: *6691484EA6B50DDDE1926A220DA01FA9E575C18A

Distill Schema using a JSON Schema

{
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "mysql::server::user": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "users": {
                    "type": "object",
                    "patternProperties": {
                        ".*": {
                            "type": "object",
                            "additionalProperties": false,
                            "properties": {
                                "host": {
                                    "type": "string",
                                    "required": true,
                                    "pattern": "^(%|([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6})$"
                                },
                                "password": {
                                    "type": "string",
                                    "required": true
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Roadmap

  • Automatic generation of JSON Schema using template input too provide a starting point
  • Allow for defining standardized Regex for known types

Installation

Download the Admin Guide PDF inside the pdfs directory for instructions.

Links

JSON Schema RFC Separating Data from Code

Related tools

Hiera

Hiera is a similar templates engine written in Ruby.

Foreman

Foreman is a very good front-end to Puppet rather then a template engine.

License

See LICENSE file in trunk.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.