Skip to content

Instantly share code, notes, and snippets.

@stevendborrelli
Last active January 30, 2018 14:21
Show Gist options
  • Save stevendborrelli/d149827ec36a93d83de3671c3654fe4c to your computer and use it in GitHub Desktop.
Save stevendborrelli/d149827ec36a93d83de3671c3654fe4c to your computer and use it in GitHub Desktop.

Converge

Converge is a configuration management tool that makes it easy to manage servers, laptops and other devices.

  • Easy to install and run.
  • Includes a powerful graph engine that automatically generates dependencies and runs tasks in parallel.
  • API-first. All communication runs through grpc.

Table of Contents

Installation

go get github.com/asteris-llc/converge

or download a release for your platform from the releases page on Github.

Usage

Converge uses HCL as a base for configuration, on top of which it add it's own semantics.

The basic unit of composition in converge is the module. Modules have parameters and can call tasks and render templates, among other things. Your usage is likely to look this this:

# install traefik
param "version" {}

module "yum" "traefik" {}

module "systemd-unit-enabled" "traefik" {
  requires = ["yum.traefik"]
}

module "systemd-unit-running" "traefik" {
  requires = ["yum.traefik"]
}

Invoke this with converge apply traefik.hcl to install Traefik from yum on your system. You can also converge plan traefik.hcl to see what changes will be made before you apply them.

Writing Modules

The content of a simple module is below:

# start a systemd unit
param "name" {}

task "start-unit" {
  check = "systemctl status {{param `name`}} | tee /dev/stderr | grep -q running"
  apply = "systemctl start {{param `name`}}"
}

Within a module, you can have tasks. Shown here is a task with two stanzas:

  • check returns the actual state, and an error code indicating if it needs to be changed
  • apply is run to create the resource controlled by this task. You can omit this stanza if you want the command to be purely informational.

If the exit code of check is non-zero, apply will be called, after which time check will be called again to get the new state and success.

A module can have multiple tasks. It can also have templates, which render data to the filesystem from the module's parameters:

# create systemd unit file
param "name" {}

param "execStart" {}

param "user" {
  default = "root"
}

param "group" {
  default = "root"
}

param "description" {
  default = "{{param `name`}}"
}

file.content "unit" {
  destination = "/etc/systemd/system/{{param `name`}}.service"

  content = <<EOF
[Unit]
Description={{param `description`}}
After=network-online.target
Wants=network-online.target

[Service]
User={{param `user`}}
Group={{param `group`}}
ExecStart={{param `execStart`}}

[Install]
WantedBy=multi-user.target
EOF
}

task "reload-daemon" {
  check    = "systemd-delta --type=overridden {{param `name`}}"
  apply    = "systemctl daemon-reload"
  requires = ["file.content.unit"]
}

This module creates a systemd unit file and registers it with the system. Note that both resource blocks have a name, and that "daemon-reload" depends on "unit". Converge uses these dependencies to determine execution order.

The arguments for the file.content resource:

  • destination: where to render the template. If you don't want to render to disk, omit this stanza. In that case, you can access the rendered template with the template template function.
  • content: this can be a string, a multi-line string (as in the example above) or any template function that returns a string. Converge intelligently renders the template until there are no more blocks, so sourcing a template from a template is fine.

Built-in Modules

Converge ships with a number of built-in modules. These can be used for common tasks without having to write your own task declarations.

File Modules

Mode (file.mode)

The file.mode module takes two required parameters:

  • destination: the file whose permissions should be checked
  • mode: the octal mode of the file

Sample:

file.mode "test" {
  destination = "test.txt"
  mode        = "0644"
}

Server

Converge can run a server to serve modules for bootstrapping. It can also host itself for downloading onto new systems. Use converge server to start it. See the --help for how to enable HTTPS.

Module Hosting

Modules are hosted at /modules/, which is a simple directory listing (control with --root, set to the current working directory by default), and will be made available publically. Use these modules by running converge plan http://your.host:8080/modules/yourModule.hcl or similar.

Binary Hosting

Converge can also host its own binary. This is turned off by default, and is enabled with the --self-serve flag to converge server. You can use this to bootstrap a new system without downloading the relevant version of converge over an external connection. It will be available at http://your.host:8080/bootstrap/binary.

Development

Tools

For linting, you'll need:

| tool | go get | | ==== | ======== | | golint | github.com/golang/lint/golint | | go tool vet | (built in) | | gosimple | honnef.co/go/simple/cmd/gosimple | | unconvert | github.com/mdempsky/unconvert | | structcheck | github.com/opennota/check/cmd/structcheck | | varcheck | github.com/opennota/check/cmd/varcheck | | aligncheck | github.com/opennota/check/cmd/aligncheck | | gas | github.com/HewlettPackard/gas |

RPC

You'll need:

  • Google's protobuf compiler, 3.0 or above.
  • The go protoc plugin: go get -a github.com/golang/protobuf/protoc-gen-go
  • The grpc gateway plugin(s): go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger

License

Converge is licensed under the Apache 2.0 license. See LICENSE for full details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment