A just-in-time / 12-factor configuration loader for Elixir projects that works great with Kubernetes and Docker Swarm.


Keywords
configuration, docker-swarm, elixir, elixir-lang, kubernetes
License
Artistic-1.0-cl8

Documentation

Weave

Note: The canonical repository is hosted here, on GitLab.com.

Hex.pm Hex.pm Hex.pm build status code coverage

A JIT configuration loader for Elixir

About

This library makes it possible to load configuration, especially secrets, from disk (Ala Docker Swarm / Kubernetes) on start-up.

Icon

“To Weave” icon by Amrit Mazumder from the Noun Project.

Installation

def deps do
  [{:weave, "~> 4.0.0"}]
end

Weave Module

In order to transform environment variables, or file contents, to runtime configuration, you must tell Weave how to handle those values.

You do this by creating a Weave module, such as:

defmodule MyApp.Weave do
  use Weave

  weave "some_environment_var_without_the_prefix",
    required: false,                # required: can be omitted and defaults to false
    handler:   {:myapp, :some_key},  # handler: can be a function, list or tuple
    handler:   [{:myapp, :some_key}, {:myapp, :another_key}],
    handler:   fn(value) -> Logger.configure(value) end)
end

Example

Lets assume:

  • We are using the environment and file loaders
  • We have the environment_prefix configured as MY_APP_
  • We have an environment variable called MY_APP_NAME
  • We have a file in configured secrets directory called db_password

Before being passed to your handler:

  • All file-names and environment variables are lower-cased
  • Environment variables have the prefix stripped
defmodule MyApp.Weave do
  use Weave

  weave "name",         handler: {:app, :name}
  weave "db_password",  required: true, handler: {:app, :password}

  # Sometimes you need to use the same value twice, so return a list.
  weave "kafka_host", handler: [
    {:kaffe, :consumer},
    {:kaffe, :producer}
  ]
end

Auto Handler Example

Warning: We intially thought this would help you reduce all the boilerplate associated with writing handlers. We're now not sure this is really worth it. Use with caution.

In-order to cut down on the boilerplate, you can use the "handler-free" approach and ensure that the values of your environment variables, or contents of files, contain:

{:auto, :app, :name, value}

Loading Configuration

You'll need to add the following to your configure function, before you prepare your supervisor:

MyApp.Weave.configure([
  only: ["database_password", "database_username", "database_host"],
  loaders: [
    {Weave.Loaders.Environment, [prefix: "MYAPP_"]},
    {Weave.Loaders.File, [directories: [
      "/run/secrets",
      "/etc/config/my_app"
    ]]}
  ]
])

Logging

Weave may log sensitive information at the debug level, stick to info in production.

Running Tests with Docker

$ make clean deps test