Skip to content

PushItToProd/groovible

Repository files navigation

Groovible

Groovible is a proof of concept DSL that compiles to a very limited subset of Ansible. The Example section below demonstrates the entirety of supported language features.

Motivation

I'm tired of writing YAML and I wanted to see if a simple DSL could do the job any better.

Example

This example is taken from the Ansible Docs and is the code used to validate the compiler in the acceptance test.

Write this DSL:

playbook {
    play {
        hosts = "webservers"
        vars {
            http_port = 80
            max_clients = 200
        }
        remote_user = "root"

        tasks {
            yum("ensure apache is at the latest version") {
                name = "httpd"
                state = "latest"
            }

            template("write the apache config file") {
                src = "/srv/httpd.j2"
                dest = "/etc/httpd.conf"

                notify "restart apache"
            }

            service("ensure apache is running") {
                name = "httpd"
                state = "started"
            }
        }

        handlers {
            service("restart apache") {
                name = "httpd"
                state = "restarted"
            }
        }
    }
}

Get this YAML:

---
- hosts: webservers
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root
  tasks:
  - name: ensure apache is at the latest version
    yum:
      name: httpd
      state: latest
  - name: write the apache config file
    template:
      src: /srv/httpd.j2
      dest: /etc/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running
    service:
      name: httpd
      state: started
  handlers:
  - name: restart apache
    service:
      name: httpd
      state: restarted

Features

The example basically covers it. Playbook scripts can contain the following blocks:

  • playbook: The outermost block, required to create a playbook.
  • play: Defines an Ansible play, must be inside a playbook block.
    • Supported variables (these map directly to the equivalent Ansible options)
      • hosts
      • remote_user
    • Supported blocks
      • vars
      • tasks
      • handlers
  • vars: Any variables defined in this block will be set on the vars section in your final playbook.
  • tasks: A special block for declaring tasks. See the Task blocks section below for more details.
  • handlers: A tasks block by another name, with the same functionality described below.

Task blocks

Task blocks (i.e. tasks and handlers) have special semantics. Inside these blocks, any method call matching the signatures (Closure cl) or (String name, Closure cl) is dynamically rewritten into an Ansible module invocation. This means that Groovible currently supports every possible Ansible module, including aci_aaa_user, azure_rm_cosmosdbaccount, and even frizzbungle, a module that doesn't exist. This also means that there are no compile-time checks to validate modules or their parameters. It is expected that invalid invocations will be caught by Ansible.

Modules can be invoked like so:

// A named task
yum("ensure apache is at the latest version") {
    name = "httpd"
    state = "latest"
}

// An unnamed task
yum {
    name = "httpd"
    state = "latest"
}

Handlers can be notified with the notify method:

template("write the apache config file") {
    src = "/srv/httpd.j2"
    dest = "/etc/httpd.conf"

    notify "restart apache"
}

Technologies used

Test

You can run unit, integration, and functional tests with ./gradlew test. The acceptance test can be run with ./gradlew acceptanceTest.

Build and Run

To use the compiler directly, build with ./gradlew fullJar and invoke the JAR under build/libs/groovible-1.0-SNAPSHOT. The CLI takes up to two arguments: the first required argument is the name of the DSL script to execute, the second optional argument is the name of the YAML file to write out to. If the second argument is not provided, the compiled YAML will be written to stdout.

For example:

$ java -jar build/libs/groovible-1.0-SNAPSHOT.jar acceptance-tests/example1_in.groovy output.yml

License

Provided under the GNU Affero General Public License, Version 3.

References

Releases

No releases published

Packages

No packages published