Packages

Weave allows you to configure your application just-in-time (JIT), embracing the 12-Factor manifesto. Weave supports loading configuration from environment variables and files, with prefix and filename filtering. Works great with Kubernetes and Docker Swarm.

Current section

Files

Jump to
weave README.md
Raw

README.md

# Weave

**Note:** The canonical repository is hosted [here](https://gitlab.com/gt8/open-source/elixir/weave), on GitLab.com.

[![Hex.pm](https://img.shields.io/hexpm/v/weave.svg)](https://hex.pm/packages/weave)
[![Hex.pm](https://img.shields.io/hexpm/l/weave.svg)](https://hex.pm/packages/weave)
[![Hex.pm](https://img.shields.io/hexpm/dw/weave.svg)](https://hex.pm/packages/weave)
[![build status](https://gitlab.com/gt8/open-source/elixir/weave/badges/master/pipeline.svg)](https://gitlab.com/gt8/open-source/elixir/weave/commits/master)
[![code coverage](https://gitlab.com/gt8/open-source/elixir/weave/badges/master/coverage.svg)](https://gitlab.com/gt8/open-source/elixir/weave/commits/master)

## 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

```elixir
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:

```elixir
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

```elixir
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:

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

### Loading Configuration

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

```elixir
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

```shell
$ make clean deps test
```